Подтвердить что ты не робот

Бит-поля и точки последовательности

Для реализации, которая упаковывает f0 и f1 в один и тот же байт, определена ли программа ниже?

struct S0 {
       unsigned f0:4;
       signed f1:4;
} l_62;

int main (void) {
       (l_62.f0 = 0) + (l_62.f1 = 0);
       return 0;
}

Меня интересует ответ для C99 и C11, если есть основания полагать, что он там другой.

В C99 все, что я нашел, было 6.5: 2:

Между предыдущей и следующей точкой последовательности объект должен иметь свой хранящееся значение, модифицированное не более одного раза путем оценки выражения. [...]

Мне непонятно, какие последствия этот параграф имеет в программе выше.

Основываясь на большом количестве рандомизированных тестов, большинство компиляторов, похоже, генерируют код, где два назначения не мешают.

4b9b3361

Ответ 1

C11 считает соседние именованные битовые поля частью одной и той же ячейки памяти. Такие битовые поля не гарантированно обновляются атомарно, другими словами, если одно обновление не секвенировано явно перед другим, то поведение undefined. 3.14 memory location затем также содержит подробное объяснение того, когда два поля можно считать находящимися в разных ячейках памяти, поэтому их обновления можно рассматривать независимо.

Если вы изменили структуру

struct S0 {
       unsigned f0:4;
       int :0;
       signed f1:4;
} l_62;

такой, что есть этот странный "разделитель местоположения памяти" между двумя битовыми полями, ваш код будет гарантированно хорош.

В случае C99 случай представляется более сложным, нет такой детальной концепции расположения памяти. В недавнем обсуждении списка рассылки ядра Linux было утверждение, что, как правило, для всех пар битовых полей была бы гарантия атомарности при обновлении любого из них. Отправной точкой этого обсуждения был случай, когда gcc загрязнил небитовое поле, соседствующее с полем бит, неожиданным образом, что привело к ложным сбоям.

Ответ 2

Назначение здесь для членов структуры. Тот факт, что они имеют одно хранилище, не должен влиять на логику. Фактически, вы фактически не выполняли задание на одно и то же.

Конечно, я не юрист языка.