声明具有以位为单位的明确大小的类数据成员。相邻的位域成员可以打包成共享和跨过各个字节。
解释
- 位域中的位数设置其所能保有的值的极限:
#include <string>
#include <iostream>
struct S{
// 2位的无符号位域,
// 允许值为 0...3
unsigned int b:2;
};
int main()
{
S s = {2};
std::cout << s.b << "\t"; // 在位域中存储值 2
s.b++;
std::cout << s.b << "\t"; // 在位域中存储值 3
s.b++; // 值4超过能表示的范围
std::cout << s.b << "\t"; // 在位域中存储值 0
for(int i = 0; i < 10; i++){
s.b++;
std::cout << s.b << "\t";
}
}
多个相邻位域通常打包在一起(尽管此行为是实现定义的):
#include <iostream>
struct S {
// 将通常占用 2 字节:
// 3 位:b1 的值
// 2 位:不使用
// 6 位:b2 的值
// 2 位:b3 的值
// 3 位:不使用
unsigned char b1 : 3, : 2, b2 : 6, b3 : 2;
};
int main()
{
std::cout << sizeof(S) << '\n'; // 通常打印 2
}
- 特殊的零大小无名位域可用于强行打破填充。它指定下个位域始于其分配单元的开始:
#include <iostream>
struct S {
// 通常将占用 2 字节:
// 3 位:b1 的值
// 5 位:不使用
// 6 位:b2 的值
// 2 位:b3 的值
unsigned char b1 : 3;
unsigned char :0; // 开始新字节
unsigned char b2 : 6;
unsigned char b3 : 2;
};
int main()
{
std::cout << sizeof(S) << '\n'; // 通常打印 2
}