#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; }; Занимает всего два байта.
Комментариев нет:
Отправить комментарий