Подтвердить что ты не робот

Как определяется/измеряется размер структуры с битовыми полями?

#include <stdio.h>

typedef struct size
{
        unsigned int a:1;
        unsigned int b:31;
        unsigned int c:1;
} mystruct;

int main()
{
        mystruct a;
        printf("%d", sizeof(a));
        return 0;
}
  • С int b:31 выход равен 8.
  • С int b:1 выход равен 4.
  • С int b:32 выход равен 12.

Может кто-нибудь объяснить причину этого?

4b9b3361

Ответ 1

Вы не говорите, знаете ли вы, какие битовые поля, но я предполагаю, что вы это делаете.

В вашей реализации, очевидно, unsigned int - это 32-битное целое число, занимающее 4 байта. Это объясняет первый и второй примеры. Очевидно, что 3 битовых поля на 33 бита не вписываются в один unsigned int, поэтому в первом примере требуется 8 байтов. 3 битовых поля, суммирующих 3 бита, безусловно, вписываются в unsigned int, а значит, только 4 байта во втором примере.

Кроме того, битовое поле не может охватывать несколько целых чисел. Это объясняет третий пример. Я не могу вспомнить, является ли это требованием стандарта или просто деталью вашей реализации. В любом случае, поскольку b - 32 бита, он заполняет целое unsigned int самостоятельно, заставляя как a, так и c занимать свои собственные unsigned int до и после середины. Следовательно, 12 байт.

Ответ 2

Это порядок, который имеет значение. Следующий код даст Output: 8

#include<stdio.h>

typedef struct size
{
        unsigned int b:32;
        unsigned int a:1;
        unsigned int c:1;
}mystruct;

int main(int argc, char const *argv[])
{
        mystruct a;
        printf("\n %lu \n",sizeof(a));
        return 0;
}

Unsigned int - это 32-битное целое число, занимающее 4 байта. Память распределена смежно в памяти.


Вариант 1:

unsigned int a:1;       // First 4 bytes are allocated
unsigned int b:31;      // Will get accomodated in the First 4 bytes
unsigned int c:1;       // Second 4 bytes are allocated

Выход: 8


Вариант 2:

unsigned int a:1;       // First 4 bytes are allocated
unsigned int b:32;      // Will NOT get accomodated in the First 4 bytes, Second 4 bytes are allocated
unsigned int c:1;       // Will NOT get accomodated in the Second 4 bytes, Third 4 bytes are allocated

Выход: 12


Вариант 3:

unsigned int a:1;       // First 4 bytes are allocated
unsigned int b:1;       // Will get accomodated in the First 4 bytes
unsigned int c:1;       // Will get accomodated in the First 4 bytes

Выход: 4


Вариант 4:

unsigned int b:32;      // First 4 bytes are allocated
unsigned int a:1;       // Second 4 bytes are allocated
unsigned int c:1;       // Will get accomodated in the Second 4 bytes

Выход: 8

Ответ 3

Выравнивание

Компилятор округляет размер структуры до 32 бит, размер каждого объекта, который он может попытаться ссылаться на 32 бита, и в то же время сохраняет порядок ваших битовых полей.

Итак, если у вас есть 32-битный элемент в среднем и 1-битном элементах с каждой стороны, то 3 32-битных слова для выделения и так: 12 байт.

В двух других случаях это всего лишь вопрос о том, как немного 32-битных объектов можно добавить в последовательность битовых полей, сохраняя при этом порядок полей.

Ответ 4

В соответствии с Стив Джессоп ответьте, чтобы выполнить свой ответ, добавив некоторые документы, которые могут помочь.

Элемент структуры или объединения может иметь любой полный тип объекта, отличный от измененного типа. Кроме того, член может быть объявлен состоящим из определенного количества бит (включая знаковый бит, если таковой имеется). Такой член называется бит-поле, его ширине предшествует двоеточие

Реализация может выделять любой адресный блок хранения, достаточно большой для хранения битового поля. Если остается достаточно места, бит-поле, которое сразу следует за другим битовым полем в структуре, должно быть упаковано в соседние биты того же блока. Если недостаточно места, то будет ли бит-поле, которое не подходит, помещается в следующий блок или перекрывается, смежные блоки определяются реализацией. Порядок распределения бит-полей внутри устройства (от высокого до низкого -order или low-order to high-order) определяется реализацией. Выравнивание адресного блока хранения не указывается.

Внутри объекта структуры члены, не являющиеся битовыми полями, и блоки, в которых расположены битовые поля, имеют адреса, которые увеличиваются в том порядке, в котором они объявлены. Указатель на объект структуры, соответствующим образом преобразованный, указывает на его первоначальный член (или если этот элемент является битовым полем, а затем блоку, в котором он находится) и наоборот. В объекте структуры может быть неназванное дополнение, но не в начале.

- ISO/IEC 9899: 201x 6.7.2.1