6

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

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

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 字节。我相信这可能是内存对齐问题。

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

4

3 回答 3

10

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

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

于 2013-02-28T07:11:03.247 回答
2

这确实是一个对齐问题。u8 eight_bit_field不是位域,它是普通的unsigned char(从名称中),并且 a char, signed charorunsigned char自然地在字节边界上对齐。

因此,您最终会在和4之间得到一些填充,在;之后得到一些填充。后者可能被派生类重用,前者永远丢失。four_bit_fieldeight_bit_field4twenty_bit_field

于 2013-02-28T07:13:21.047 回答
2

尝试强制对齐到 1 个字节:

#pragma pack(1)
class Test {
    u8 four_bit_field : 4;
    u8 eight_bit_field : 8;
    u32 twenty_bit_field : 20;
};
#pragma pack()
于 2013-02-28T07:54:56.997 回答