Битовые поля
Объявляет член с явной шириной в битах. Смежные члены битовых полей могут быть упакованы для совместного использования и перекрытия отдельных байтов.
Объявление битового поля — это объявление члена структуры (struct) или объединения (union), использующее следующий дескриптор (declarator):
идентификатор (необязательно) : ширина
|
| идентификатор | - | имя битового поля, которое объявляется. Имя необязательно: безымянные битовые поля вводят указанное количество битов заполнения |
| ширина | - | целое число константное выражение со значением, большим или равным нулю и меньшим или равным числу битов в базовом типе. Если оно больше нуля, это число битов, которые будет занимать это битовое поле. Значение ноль допускается только для безымянных битовых полей и имеет специальное значение: оно указывает, что следующее битовое поле в определении класса будет начинаться с границы блока выделения. |
Объяснение
Битовые поля могут иметь только один из этих трех(до C99) – четырех(с C99)(до C23) типов (возможно, с квалификаторами const или volatile):
-
unsigned int, для беззнаковых битовых полей (unsigned int b:3;имеет диапазон0..7) -
signed int, для знаковых битовых полей (signed int b:3;имеет диапазон-4..3) -
int, для битовых полей с реализацией определённого знака (Обратите внимание, что это отличается от значения ключевого словаintв других местах, где оно означает «signed int»). Например,int b:3;может иметь диапазон значений0..7или-4..3.
|
(с C99) |
|
(с C23) |
Дополнительные типы, определяемые реализацией, могут быть допустимы. Также определяется реализацией, может ли битовое поле иметь атомарный тип.(с C11) Число битов в битовом поле (ширина) задаёт предел диапазона значений, которые оно может содержать:
#include <stdio.h>
struct S
{
// three-bit unsigned field,
// allowed values are 0...7
unsigned int b : 3;
};
int main(void)
{
struct S s = {7};
++s.b; // unsigned overflow
printf("%d\n", s.b); // output: 0
}Разрешено (и обычно используется) несколько смежных битовых полей, упакованных вместе:
#include <stdio.h>
struct S
{
// will usually occupy 4 bytes:
// 5 bits: value of b1
// 11 bits: unused
// 6 bits: value of b2
// 2 bits: value of b3
// 8 bits: unused
unsigned b1 : 5, : 11, b2 : 6, b3 : 2;
};
int main(void)
{
printf("%zu\n",sizeof(struct S)); // usually prints 4
}Специальное безымянное битовое поле с шириной ноль разбивает заполнение: оно указывает, что следующее битовое поле начинается с начала следующего блока выделения:
#include <stdio.h>
struct S
{
// will usually occupy 8 bytes:
// 5 bits: value of b1
// 27 bits: unused
// 6 bits: value of b2
// 15 bits: value of b3
// 11 bits: unused
unsigned b1 : 5;
unsigned :0; // start a new unsigned int
unsigned b2 : 6;
unsigned b3 : 15;
};
int main(void)
{
printf("%zu\n", sizeof(struct S)); // usually prints 8
}Поскольку битовые поля не обязательно начинаются с начала байта, адрес битового поля нельзя получить. Указатели на битовые поля невозможны. Битовые поля нельзя использовать с sizeof и _Alignas(с C11).
Примечания
Следующие случаи использования битовых полей вызывают неопределённое поведение:
- Вызов
offsetofдля битового поля
Следующие свойства битовых полей являются неопределёнными:
- Выравнивание блока выделения, содержащего битовое поле
Следующие свойства битовых полей являются зависящими от реализации:
- Обрабатываются ли битовые поля типа
intкак знаковые или беззнаковые - Допускаются ли типы, отличные от
int,signed int,unsigned int,_Bool(с C99) и (возможноunsigned)_BitInt(N)(с C23)
|
(с C11) |
- Может ли битовое поле перекрывать границу блока выделения
- Порядок битовых полей внутри блока выделения (на некоторых платформах битовые поля упаковываются слева направо, на других — справа налево)
|
Несмотря на то, что количество битов в объектном представлении |
(с C99) |
В языке программирования C++ ширина битового поля может превышать ширину базового типа (но дополнительные биты являются битами заполнения), а битовые поля типа int всегда знакового типа.
Ссылки
- Стандарт C23 (ISO/IEC 9899:2023):
- 6.7.2.1 Спецификаторы структур и объединений
- Стандарт C17 (ISO/IEC 9899:2018):
- 6.7.2.1 Спецификаторы структур и объединений
- Стандарт C11 (ISO/IEC 9899:2011):
- 6.7.2.1 Спецификаторы структур и объединений
- Стандарт C99 (ISO/IEC 9899:1999):
- 6.7.2.1 Спецификаторы структур и объединений
- Стандарт C89/C90 (ISO/IEC 9899:1990):
- 3.5.2.1 Спецификаторы структур и объединений
См. также
| Документация C++ для Битового поля |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/c/language/bit_field