Страницы

Поиск по вопросам

понедельник, 24 декабря 2018 г.

sizeof() и битовые поля

Вот имеется структура:
struct Data { char A : 4; unsigned B: 12; };
Если убрать в ней поле A, то sizeof(Data) выдаст 4. Нормально. Убрать поле B, sizeof(Data) вернет 1. Нормально. А если оставить A и B, то sizeof(Data) вернет 8!. Непонятно.
Почему 8, а не 5?


Ответ

Низкоуровневые детали размещения в памяти битовых полей не стандартизованы и определяются реализацией.
Однако с абстрактной точки зрения битовые поля выделяются внутри т.наз. единиц аллокации. Обычно единица аллокации - это просто полноценное поле того самого типа, который указан в объявлении битового поля. Последовательные битовые поля пакуются в последнюю выделенную единицу аллокации, пока она не заполнится.
И в некоторых реализациях смена типа в объявлении битового поля приводит к досрочному завершению заполнения текущей единицы аллокации и выделению новой единицы аллокации. Т.е. в данном случае при работе с такими реализациями в вашем примере получится две отдельные единицы аллокации: типа char и типа unsigned. В таких реализациях эти единицы аллокации обычно ведут себя так же как и обычные поля соответствующего типа, т.е. фактически вы имеете дело с
struct Data { char unit1; unsigned unit2; };
А такая структура имеет размер 8 из соображений выравнивания. Если же вы явно запросите выравнивание в 1, то такая структура получит размер 5.
В компиляторе GCC, например, используется совсем другой подход к выделению новых единиц аллокации и там ваша структура получит размер 4.

Комментариев нет:

Отправить комментарий