c++ - 位域是对齐数据的一种方式吗?
问题描述
#include <iostream>
struct S {
// will usually occupy 2 bytes:
// 3 bits: value of b1
// 2 bits: unused
// 6 bits: value of b2
// 2 bits: value of b3
// 3 bits: unused
unsigned char b1 : 3, : 2, b2 : 6, b3 : 2;
};
int main()
{
std::cout << sizeof(S) << '\n'; // usually prints 2
}
为什么这2位未使用?
不能只是:
unsigned char b1 : 3, b2 : 6, b3 : 2;
这是一种填充方式吗?
如果(如果我没记错的话)这个位字段实际上改变了变量的大小,或者它们只是编译器的“建议”,谁能解释我?(作为inline
关键字)。如果位字段按我的理解工作,您将能够在 1 位上存储布尔值(这是不可能的,因为内存被分割为 1 个字节的块)
解决方案
cppreference 上的示例只是说明标准中不能保证位域映射到相邻的内存区域,尽管大多数明智的实现都会这样做。提供的代码片段故意使用 2 位的未命名位文件从存储中请求两位 - 并且只是展示了位文件可以未命名。这使得表示该结构所需的总位数为 14。
14 位可以打包成 2 个字节(16 位),所以这是一般实现的预期 - 但不能保证会发生。
最后但并非最不重要的一点是,如果您发现自己处于在结构上使用位域的位置,请不要三思而后行。它们实际上提供优势的情况很少,因此您需要确保您正在处理其中一种情况。
推荐阅读
- python-3.x - 如何使对象与 tkinter 发生碰撞
- jenkins - 如何配置 Jenkins Pipeline,以便自动发送带有自定义正文的电子邮件?
- 2d - 我可以在 Godot 中进行半圆碰撞吗?
- json - JSON Schema 的什么变体是 Google Sheets API 的 JSON 资源?
- splunk - 如何优化以下 Splunk 查询?
- java - slf4j 在计划任务线程中不起作用
- android - 每次调用 onCreate 方法时都不会调用 ViewModel 方法
- python - 显示 pandas 列 - 从宽到长
- python - 从嵌套列表中删除不需要的文本
- php - 如何在电子邮件 Codeigniter 中循环收件人