Страницы

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

вторник, 31 декабря 2019 г.

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

#cpp #структуры #sizeof


Вот имеется структура:

struct Data
{
    char A : 4;
    unsigned B: 12;
};


Если убрать в ней поле A, то sizeof(Data) выдаст 4. Нормально.
Убрать поле B, sizeof(Data) вернет 1. Нормально.
А если оставить  A и B, то sizeof(Data) вернет 8!. Непонятно.  

Почему 8, а не 5?
    


Ответы

Ответ 1



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

Ответ 2



Если поле имеет размер 12 бит и хочется сэкономить на размере, то совершенно нет смысла делать его типом int, имеющим размер 4 байта. Структуру из примера можно переписать так struct Data { uint16_t A : 4; uint16_t B : 12; }; Занимает всего два байта.

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

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