使用C ++类中的位字段的未对齐属性

时间:2013-02-28 07:07:13

标签: c++ bit-fields

我正在尝试使用C ++中的位字段来实现特定的类大小,但由于某种原因,它比我预期的要大。

问题是,一个32位(4字节)的类报告(当作为参数传递给sizeof时)5个字节。示例类如下:

typedef unsigned char u8;
typedef unsigned int u32;

class Test {
    u8 four_bit_field : 4;
    u8 eight_bit_field;
    u32 twenty_bit_field : 20;
}__attribute__((packed));

如果切换four_bit_fieldeight_bit_field位置,sizeof将返回正确的大小,4个字节。我相信它可能是一个记忆排列问题。

那么,有人知道这种行为背后的原因吗?而且,最重要的是,如何在不改变任何职位的情况下解决这个问题。

3 个答案:

答案 0 :(得分:10)

没有位计数的u8字段正在与下一个字节边界对齐,而不是与其他位字段打包在一起。因此,前4位占用一个字节,后8位取一个字节,最后20位取3个字节,共计5个。

如果向8位字段添加位字段大小,它将起作用,请参阅http://ideone.com/Bexw6l

答案 1 :(得分:2)

实际上,这是一个对齐的问题。 u8 eight_bit_field不是一个位域,它是一个简单的unsigned char(来自名称),而charsigned charunsigned char在字节边界上自然对齐

因此,4之后,four_bit_fieldeight_bit_field以及4位填充之间的twenty_bit_field位填充为{{1}}位;后者可能由派生类重复使用,前者永远丢失。

答案 2 :(得分:2)

尝试将对齐强制为1个字节:

#pragma pack(1)
class Test {
    u8 four_bit_field : 4;
    u8 eight_bit_field : 8;
    u32 twenty_bit_field : 20;
};
#pragma pack()