Вот имеется структура:
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.
Комментариев нет:
Отправить комментарий