在C11中工作,以下结构:
struct S {
unsigned a : 4;
_Bool b : 1;
};
由GCC布置为使用4位的
unsigned
(4个字节),然后使用使用1位的_Bool
(4个字节),总大小为8个字节。请注意,C99和C11特别允许
_Bool
作为位字段成员。 C11标准(可能还有C99)也在第6.7.2.1节“结构和联合说明符”¶11中指出:An implementation may allocate any addressable storage unit large enough to hold a bit-field. If enough space remains, a bit-field that immediately follows another bit-field in a structure shall be packed into adjacent bits of the same unit.
因此,我认为上面的成员
b
应该已经打包到分配给成员a
的存储单元中,导致结构的总大小为4个字节。当两个成员使用相同的类型,或者一个是
unsigned
而另一个是signed
时,GCC的行为正确,并且确实发生了打包,但是GCC认为unsigned
和_Bool
类型太不同,以至于无法正确处理它们。有人可以确认我对标准的解释,而这确实是GCC错误吗?
我也对解决方法感兴趣(某些编译器开关,编译指示,
__attribute__
...)。我将gcc 4.7.0与
-std=c11
一起使用(尽管其他设置显示了相同的行为。)
最佳答案
所描述的行为与C99和C11标准不兼容,但是为了与MSVC编译器(具有不寻常的结构打包行为)二进制兼容而提供。
幸运的是,可以在将__attribute__((gcc_struct))
应用于结构的代码中禁用此功能,也可以使用命令行开关-mno-ms-bitfields
禁用它(请参阅documentation)。
关于gcc - GCC位域实现中的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11283164/