gcc - GCC位域实现中的错误

标签 gcc c99 bit-fields c11 compiler-bug

在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/

相关文章:

python - 创建一个带有位域的枚举

c++ - 将 `nullptr` 分配给 `bool` 类型。哪个编译器是正确的?

c - 是否有任何 C 标准中定义的通用 printf-ish 例程

c - 是否可以将第三种#include 指令中的 "glue"预处理器标记放入双引号中?

c - 在C89中有效的程序,但在C99中无效

c - 位域 VS。位掩码

c - 位字段变量命名约定和无效类型错误 gcc 4.2.1 freebsd 7

c - 如何在 C 中使用静态断言来检查传递给宏的参数类型

c++ - 为什么 Qt 会从 .qrc 生成一个 .cpp 文件?

c++ - g++ undefined reference 虽然包含所有文件