联合中位字段的VStudio c++对齐

VStudio c++ alignment of bitfield in union

本文关键字:VStudio c++ 对齐 字段      更新时间:2023-10-16

在VStudio 2010中,我试图创建一个并集来方便地访问2字节的值:

#pragma pack(push,1) // disable padding
typedef struct {
uint8_t r:3;
uint8_t g:3;
uint8_t b:3;
}tsRgb;
typedef union {
uint16_t raw;
tsRgb rgb; 
}tPixelData;
#pragma pack(pop)
int main(){
tPixelData pixel;
pixel.raw = 0xABE5;
return 0;
}

我希望看到pixel.r=5,pixel.g=4,pixer.b=7。r和g是可以的,但是b是3。

我做错了什么?我想我没有正确地拼写这些比特?

第三个字段将在一个单独的字节中。

在VC++中,位字段不跨越底层类型的边界。当您使用3+3位时,只剩下2位,所以下一个字段将使用新字节中的3位。

如果使用uint16_t而不是uint8_t,它可能会更好地工作。

"禁用填充"适用于字节级别,而不是位级别。

按照您的意愿使用位字段从根本上来说是有问题的。根据C标准,6.7.2.1结构和并集说明符,第11段(因为您的问题也标记为C):

一个实现可以分配任何大的可寻址存储单元足以容纳一个比特场。如果还有足够的空间紧跟在结构中的另一个位字段之后的被打包到同一单元的相邻比特中。如果空间不足剩余,是否将不适合的位字段放入下一个单元或重叠的相邻单元是实现定义。位字段在单位(从高阶到低阶或从低阶到高阶)是实现定义。可寻址存储器的对齐单位未指定。

位字段中位的布局和对齐都是由实现定义的。字段可以跨越也可以不跨越存储单元边界,它们可以按任何顺序存储。

它们根本不便携。