GCC实现位域的一个错误

ndk*_*pel 9 gcc c99 compiler-bug bit-fields c11

在C11中工作,结构如下:

struct S {
  unsigned a : 4;
  _Bool    b : 1;
};
Run Code Online (Sandbox Code Playgroud)

由GCC布局为unsigned(4字节),其中使用4位,然后是_Bool(4字节),其中使用1位,总大小为8字节.

注意,C99和C11特别允许_Bool作为位字段成员.C11标准(也可能是C99)也在§6.7.2.1"结构和联合说明符"中声明:

实现可以分配任何足够大的可寻址存储单元来保存位字段.如果剩余足够的空间,则紧跟在结构中的另一个位字段之后的位字段将被打包到相同单元的相邻位中.

所以我认为b上面的成员应该被打包到为成员分配的存储单元中a,从而产生一个总大小为4字节的结构.

GCC正确的行为和包装不使用相同类型的两个成员发生时,或者当一个unsigned和其他signed,但类型unsigned_Bool似乎是由海湾合作委员会被认为过于鲜明它正确地处理它们.

有人可以证实我对标准的解释,这确实是一个GCC错误吗?

我也对一种解决方法感兴趣(一些编译器开关,pragma,__attribute__......).

我正在使用gcc 4.7.0 -std=c11(尽管其他设置显示相同的行为.)

ndk*_*pel 10

所描述的行为与C99和C11标准不兼容,但提供与MSVC编译器的二进制兼容性(具有不寻常的结构包装行为.)

幸运的是,可以在__attribute__((gcc_struct))应用于struct 的代码中或使用命令行开关禁用它-mno-ms-bitfields(请参阅文档).