Размер битового поля не такой, как ожидалось, почему?

Почему это битовое поле имеет размер 4?
Могу ли я сделать так, чтобы он имел размер 2 (как это очевидно предполагается в приведенном ниже коде), или это невозможно сделать чисто?

struct S
{
    unsigned short x : 15;
    bool a : 1;
};

int main() { return sizeof(S); }

1 ответ

Это невозможно сделать со стандартным C++, но можно использовать специфическую для компилятора прагму или атрибут для вашей структуры.

в VC++ это #pragma pack

Также, чтобы получить только размер 2, вы должны сделать это:

#pragma pack(1)
struct s{
  unsigned short s1: 15;
  unsigned short b1: 1;
};

С #pragma pack в вашем коде следующим образом:

struct S
{
    unsigned short x : 15;
    bool a : 1;
};

Гипотетический макет памяти будет:

----------------------
+ 1 | 2 | 3 | 4 | 5 | ..
+   x   | a |
+---------------------

Следовательно он занимает 3 байта

изменения bool a в unsigned short a Вы получаете это:

-------------------------
+ 1 | 2 | 3 | 4 | 5| ..
+   x |a|
-------------------------

Который занимает всего 2 байта.

Компилятор решает, что, поскольку второе короткое замыкание занимает всего 1 бит, можно просто сжать структуру в 2 байта. Но если используется элемент структуры другого типа (например, bool в вашей реализации S) компилятор считает, что, поскольку типы различаются, он не может сжать 1 бит в unsigned short(потому что он пересекает границу типа - к сожалению, реализация определена). Отсюда вы получаете 3 байты для sizeof() вместо 2.

Другие вопросы по тегам