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

Что означает двоеточие в объявлении структуры, например: 1,: 7,: 16 или: 32?

Что означает следующий код на С++?

unsigned char a : 1; 
unsigned char b : 7;

Я предполагаю, что он создает два char a и b, и оба они должны быть длиной один байт, но я понятия не имею, что делает часть ": 1" и ": 7".

4b9b3361

Ответ 1

1 и 7 - размер бит, чтобы ограничить диапазон значений. Они обычно встречаются в структурах и союзах. Например, на некоторых системах (зависит от char правил ширины и упаковки и т.д.) Код:

typedef struct {
    unsigned char a : 1;
    unsigned char b : 7;
} tOneAndSevenBits;

создает 8-битное значение, один бит для a и 7 бит для b.

Обычно используется в C для доступа к "сжатым" значениям, таким как 4-разрядный nybble, который может содержаться в верхней половине 8-разрядного char:

typedef struct {
    unsigned char leftFour  : 4;
    unsigned char rightFour : 4;
} tTwoNybbles;

Для юристов языка среди нас раздел 9.6 стандарта С++ 11 подробно объясняет это, слегка перефразируя:


Бит-поля [class.bit]

Член-декларатор формы

      идентификатор <суб > неавтоматическогосуб >   атрибут спецификатор <суб > неавтоматическогосуб >    :   постоянное выражение

указывает бит-поле; его длина начинается с имени битового поля двоеточием. Необязательный атрибут-спецификатор относится к объявляемому объекту. Атрибут битового поля не является частью типа члена класса.

Постоянное выражение должно быть интегральным постоянным выражением со значением, большим или равным нулю. Значение интегрального выражения константы может быть больше, чем количество бит в представлении объекта типа бит-полей; в таких случаях дополнительные биты используются как биты заполнения и не участвуют в представлении значений бит-поля.

Распределение бит-полей внутри объекта класса определяется реализацией. Выравнивание битовых полей определяется реализацией. Бит-поля упаковываются в некоторые адресные единицы выделения.

Примечание: блоки выделения блоков бит на некоторых машинах, а не другие. Бит-поля назначаются справа налево на некоторых машинах, слева направо на других. - конец примечания

Ответ 2

Я считаю, что это будут битподы.

Ответ 3

Строго говоря, битовое поле должно быть int, unsigned int или _Bool. Хотя большинство компиляторов будет использовать любой интегральный тип.

Ref C11 6.7.2.1:

Поле бит должно иметь тип, который является квалифицированным или неквалифицированным версия _Bool, подписанный int, unsigned int или какой-либо другой тип реализации.

Ваш компилятор, вероятно, выделит 1 байт хранилища, но он сможет захватить больше.

Ref C11 6.7.2.1:

Реализация может выделять любой адресный блок хранения большой достаточно, чтобы удержать бит-поле.

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

Ref C11 6.7.2.1:

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