Смещение в структуре с битовыми полями

Если у нас есть структура с битовыми полями, то как последующие члены выравниваются в структуре? Рассмотрим следующий код:

struct A{
    int a:1;
    char b;     // at offset 1
};

struct B{
    int a:16;
    int b: 17;
    char c;     // at offset 7
};

printf("Size of A: %d\n", (int)sizeof(struct A));
printf("Offset of b in A: %d\n", (int)offsetof(struct A, b));

printf("Size of B: %d\n", (int)sizeof(struct B));
printf("Offset of c in B: %d\n", (int)offsetof(struct B, c));

Вывод:

Size of A: 4
Offset of b in A: 1
Size of B: 8
Offset of c in B: 7

Здесь в первом случае b выделяется только во втором байте структуры без какого-либо дополнения. Но во втором случае, когда битовые поля переполняют 4 байта, c выделяется в последнем (восьмом) байте.

Что происходит во втором случае? Каково правило для заполнения в структурах с использованием полей бит вообще?

Ответ 1

как последующие члены выравниваются в структуре?

Никто не знает. Это поведение, определяемое реализацией и, следовательно, специфическое для компилятора.

Что происходит во втором случае?

Компилятор может иметь добавленные байты заполнения или биты заполнения. Или порядок бит структуры может отличаться от ожидаемого. Первый элемент структуры не обязательно содержит MSB.

Каково правило для заполнения в структурах с использованием полей бит вообще?

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

Бит-поля очень слабо определяются стандартом. Они по сути бесполезны ни для чего другого, кроме кусков булевых флагов, выделенных в произвольных местах в памяти. Я бы посоветовал вместо этого использовать битовые операторы на простых целых числах. Затем вы получаете 100% детерминированный, переносимый код.

Ответ 2

Я бы сделал небольшой пример. Надеюсь, что это будет ясно: Рассмотрим две структуры:

struct {
    char a;
    int b;
    char c;
} X;

Versus.

struct {
    char a;
    char b;
    int c;
} Y;

Немного больше объяснений относительно комментариев ниже:

Все ниже - это не 100%, а общий способ построения структур в 32-битной системе, где int - 32 бита:

Структура X:

|     |     |     |     |     |     |     |     |     |     |     |     |
 char  pad    pad   pad   ---------int---------- char   pad   pad   pad   = 12 bytes

struct Y:

|     |     |     |     |     |     |     |     |
 char  char  pad   pad   ---------int----------        = 8 bytes

Спасибо

Некоторая ссылка::

Структура данных Выравнивание-википедия