C C  ·  25 вопросов  ·  ~70 мин  ·  ⏱ Таймер 10:00  ·  Средний  · 

const, volatile и restrict

Тест отделяет три часто смешиваемых механизма: `const` ограничивает изменение через выражение, `volatile` сохраняет особые обращения, а `restrict` задаёт обещание об отсутствии конфликтующих путей доступа. Задания проверяют последствия для интерфейсов, регистров устройств, потоков и оптимизатора.

Отвечено: 0 из 25
⏱ --:--
0%
💡 Инструкция: Выберите один ответ из пяти. На 25 вопросов отведено 70 минут. Код читайте построчно: часть заданий проверяет вывод, часть — поиск дефекта, переносимость и безопасное исправление. После завершения откроются объяснения и профиль по 5 темам.
Вопрос 1 из 25
Что запрещает `const int *p`?
CC17
const int *p=&x;
Вопрос 2 из 25
Что запрещает `int * const p = &x`?
CC17
int * const p=&x;
Вопрос 3 из 25
Как объявить неизменяемый указатель на неизменяемый int?
CC17
int value = 7;
/* p нельзя переназначить и через p нельзя изменить value. */
Вопрос 4 из 25
Можно ли снять const кастом и записать в объект, изначально объявленный const?
CC17
const int x=3;
int *p=(int*)&x;
*p=4;
Вопрос 5 из 25
Почему параметр чтения лучше объявить `const struct cfg *`?
Вопрос 6 из 25
Для чего volatile уместен в системном C?
CC17
volatile unsigned *status=(volatile unsigned*)DEVICE_ADDR;
while((*status&READY)==0){}
Вопрос 7 из 25
Гарантирует ли volatile атомарность `counter++` между потоками?
CC17
volatile unsigned counter;
/* два потока выполняют counter++ */
Вопрос 8 из 25
Почему чтение volatile-регистра лучше не повторять без необходимости?
Вопрос 9 из 25
Что означает `volatile const uint32_t *reg`?
CC17
volatile const uint32_t *reg;
Вопрос 10 из 25
Может ли компилятор держать volatile-значение только в регистре между двумя выражениями, полностью убрав второе чтение?
CC17
unsigned a=*reg;
unsigned b=*reg;
Вопрос 11 из 25
Какой тип указателя разрешён для просмотра байтового представления любого объекта?
CC17
struct packet obj = read_packet();
/* Требуется изучить объектное представление obj по отдельным байтам. */
Вопрос 12 из 25
Почему чтение int через float* после каста опасно?
CC17
int x=0x3f800000;
float f=*(float*)&x;
Вопрос 13 из 25
Как переносимо скопировать биты uint32_t в float того же размера?
CC17
float f;
uint32_t u = bits;
_Static_assert(sizeof f == sizeof u, "size");
/* перенесите объектное представление без нарушения правил доступа */
Вопрос 14 из 25
Что такое алиасинг?
Вопрос 15 из 25
Почему функция с двумя `int *` должна учитывать p==q?
CC17
void update(int *p,int *q){ *p+=1; *q*=2; }
Вопрос 16 из 25
Что обещает restrict в параметре `int *restrict dst`?
CC17
void add(size_t n,int *restrict dst,const int *restrict src);
Вопрос 17 из 25
Можно ли передать одной restrict-функции перекрывающиеся dst и src?
Вопрос 18 из 25
Исправляет ли добавление `volatile` гонки данных и нарушения порядка доступа к аппаратной памяти?
Вопрос 19 из 25
Почему restrict может ускорить векторизацию?
CC17
for(size_t i=0;i<n;i++) dst[i]+=src[i];
Вопрос 20 из 25
Что важнее перед добавлением restrict ради скорости?
Вопрос 21 из 25
Какой флаг GCC/Clang помогает предупреждать о снятии const кастом?
CC17
void update(const int *src) {
    int *p = (int *)src; /* нужно включить предупреждение о снятии квалификатора */
    *p = 1;
}
Вопрос 22 из 25
Почему проверки только со сборкой `-O0` недостаточно для поиска дефекта, связанного с псевдонимами указателей?
Вопрос 23 из 25
Что полезно сравнить при подозрении на volatile/MMIO ошибку?
CC17
cc -O2 -S driver.c -o driver.s
Вопрос 24 из 25
Обнаружит ли UBSan все нарушения правила строгого алиасинга?
Вопрос 25 из 25
Какой минимальный эксперимент убедительнее?
CПлан эксперимента
for cc in gcc clang; do
  $cc -O0 case.c -o a0 && ./a0
  $cc -O2 case.c -o a2 && ./a2
done

Ответьте на все 25 вопросов, чтобы получить результат

🔗 Встроить тест на свой сайт (iframe) ▼

Скопируйте код и вставьте в любое место на вашем сайте:

Также доступна прямая ссылка на embed-страницу