Работа в С11, следующей структуры:ошибка в реализации GCC битовых полей
struct S {
unsigned a : 4;
_Bool b : 1;
};
получает уложены путем GCC в качестве unsigned
(4 байта) из которых используются 4 бита, а затем _Bool
(4 байта), из которых 1 бит используется для общего размера 8 байтов.
Обратите внимание, что C99 и C11 специально разрешают _Bool
в качестве элемента битового поля. Стандарт C11 (и, вероятно, C99 тоже) также говорится, под §6.7.2.1 «Структура и объединение спецификаторы» ¶11 что:
Реализация может выделить любой адресуемый блок хранения достаточно большой, чтобы держать битовое поле. Если остается достаточно места, бит-поле, которое сразу следует за другим битовым полем в структуре, должно быть упаковано в соседние биты того же блока.
Поэтому я считаю, что член b
выше, должен был упакован в блок памяти, выделенный для члена a
, в результате чего структур от общего размера 4 байта.
НКУ ведет себя правильно и упаковка имеет место при использовании тех же типов для двух членов, или когда один unsigned
и другой signed
, но типы unsigned
и _Bool
, кажется, считаются слишком отличается от GCC для того, чтобы справиться с ними правильно.
Может кто-то подтвердить мою интерпретацию стандарта и что это действительно ошибка GCC?
Меня также интересует обход (некоторый переключатель компилятора, прагма, __attribute__
...).
Я использую GCC 4.7.0 с -std=c11
(хотя другие параметры показывают такое же поведение.)
Обратите внимание, что расширение GCC '__attribute__ ((упакованное))' может применяться к членам здесь , но ортогонален этой проблеме (в результате получается структура размером 4 + 1 = 5, то есть с той же проблемой.) – ndkrempel
Связано: http://stackoverflow.com/questions/308364/c-bitfield-packing-with -bools (но относится к C++, что не так требовательно в его формулировке по битовым полям.) – ndkrempel
Согласно ответу на вопрос, связанный выше, это поведение не произошло в gcc 4.2.4, поэтому может быть регрессия с тех пор. – ndkrempel