在 C11 中工作,以下结构:
struct S {
unsigned a : 4;
_Bool b : 1;
};
由 GCC 布局为一个unsigned
(4 个字节),其中使用了 4 个位,然后是一个_Bool
(4 个字节),其中使用了 1 个位,总大小为 8 个字节。
请注意,C99 和 C11 特别允许_Bool
作为位域成员。C11 标准(可能还有 C99)还在 §6.7.2.1 'Structure and union specifiers' ¶11 中声明:
实现可以分配任何大到足以容纳位字段的可寻址存储单元。如果有足够的空间剩余,紧跟在结构中另一个位域之后的位域将被打包到同一单元的相邻位中。
所以我认为b
上面的 member 应该已经被打包到为 member 分配的存储单元中a
,从而产生了一个总大小为 4 字节的结构。
GCC 行为正确,并且在对两个成员使用相同类型时,或者当一个 isunsigned
和另一个时,确实会发生打包,但是GCC 似乎认为signed
类型unsigned
和类型过于不同,无法正确处理它们。_Bool
有人可以确认我对标准的解释,这确实是一个 GCC 错误吗?
我也对解决方法感兴趣(一些编译器开关,编译指示,__attribute__
...)。
我正在使用 gcc 4.7.0 -std=c11
(尽管其他设置显示相同的行为。)