c - 位域实际上是如何工作的?在什么情况下会发生位填充?
问题描述
我最近被介绍到位域。我有一个以下工会。
typedef struct
{
uint16_t var1:16;
uint32_t var2:28;
uint8_t var3:8;
uint8_t var4:8;
uint8_t var5:8;
uint8_t var6:8;
bool var7:1;
bool var8:1;
bool var9:1;
bool var10:1;
bool var11:1;
uint8_t var12:1;
uint8_t var13:7;
uint8_t var14:7;
uint32_t var15:18;
uint16_t var16:10;
uint8_t var17:4;
} packet_bit_map;
typedef union
{
packet_bit_map packetsArrived ;
uint8_t packetRaw[16];
} packetDecode;
这个想法是复制来自外部设备的数据流,它是 16 个字节的单个字节值,然后使用位域结构来访问特定信息。但是在调试后我无法做到这一点,我发现联合packetDecode的大小最终为 20 而不是 16 ,因为packetArrived持有 20bytes 。为什么会这样?以及如何避免这种填充?
编辑:我知道一种使用属性填充的解决方案,但遗憾的是我不能在我的项目中使用内联函数。
解决方案
如果你想打包:
- 将字段分组为完全适合的类型。
- 不要
bool
用作位域的类型。 - 打包结构(它取决于实现)
typedef struct __attribute__((packed))
{
uint16_t var1:16;
uint64_t var2:28;
uint64_t var3:8;
uint64_t var4:8;
uint64_t var5:8;
uint64_t var6:8;
uint64_t var7:1;
uint64_t var8:1;
uint64_t var9:1;
uint64_t var10:1;
uint16_t var11:1;
uint16_t var12:1;
uint16_t var13:7;
uint16_t var14:7;
uint32_t var15:18;
uint32_t var16:10;
uint32_t var17:4;
} packet_bit_map;
推荐阅读
- python - 更改中间激活/输出并观察 TF2/Keras 中的预测
- php - 如何将自动增量 ID 重置为以前的 ID
- java - java:如果我为变量分配了与之前相同的值,它会改变内存还是 JIT 能识别这一点?
- javascript - 在控制台中模拟调用 onMouseDown
- python - 获取数字列表的更快方法
- wordpress - 我可以在哪里编辑似乎不在代码中的 wordpress 文本?
- ruby-on-rails - 我无法在我的 Rails 应用程序中创建 manifest.json
- wordpress - Wordpress 回显或获取除最后 6 个字符外的单个帖子标题
- mongodb - 如何在 F# 中对 Mongo 集合进行排序
- javascript - 获取符号名称