【发布时间】:2021-09-09 07:06:24
【问题描述】:
我最近被介绍到位域。我有一个以下工会。
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 ,因为 packetsArrived 持有 20bytes 。为什么会这样?以及如何避免这种填充?
编辑:我知道一种解决方案是使用属性填充,但遗憾的是我不能在我的项目中使用内联函数。
【问题讨论】:
-
TL;DR:“位域实际上是如何工作的?”不良。 “在什么情况下会发生位填充?”没有人知道,因为它没有标准化。 “我最近被介绍到位领域”由谁?通过一些值得信赖的 C 源或随机的“友好”人?
-
我不久前写了一个关于why bitfields should not be used for serialization的答案。我认为大部分适用于您的情况。
-
即使你把它打包成 16 个字节,也不能保证结构会匹配源。 - 打包的顺序也是实现定义的。为此目的使用位域不是一个好主意。使用位域的理由很少,也没有办法使其可移植。
标签: c embedded deserialization union bit-fields