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

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

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

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

Ответы [ 3 ]

56 голосов
/ 22 октября 2009

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

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

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

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

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

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


Битовые поля [class.bit]

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

идентификатор опт атрибут-спецификатор опт : константа-выражение

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

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

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

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

9 голосов
/ 22 октября 2009

Полагаю, это будут битовые поля.

1 голос
/ 21 июля 2016

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

Ссылка C11 6.7.2.1:

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

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

Ссылка C11 6.7.2.1:

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

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

Ссылка C11 6.7.2.1:

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

...