Как определяется / измеряется размер структуры с битовыми полями? - PullRequest
34 голосов
/ 09 ноября 2010
#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.

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

Ответы [ 4 ]

38 голосов
/ 21 апреля 2013

Это порядок, который имеет значение. Следующий код даст вывод: 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

29 голосов
/ 09 ноября 2010

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

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

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

10 голосов
/ 09 ноября 2010

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

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

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

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

9 голосов
/ 23 декабря 2012

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

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

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

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

- ИСО / МЭК 9899: 201x 6.7.2.1

...