在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(尽管其他设置显示相同的行为.)
可能重复:
使用bool进行C++位域打包
bool在位域定义中使用C++的关键字是否安全?
就像是:
struct flags {
bool a : 1;
bool b : 1;
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用C++与Ada代码进行交互,因此我使用位字段定义结构,以便所有数据在两种语言中都处于相同的位置.以下不是我正在做的,但概述了问题.以下也是VS2008中的控制台应用程序,但这不是超级相关的.
using namespace System;
int main() {
int array1[2] = {0, 0};
int *array2 = new int[2]();
array2[0] = 0;
array2[1] = 0;
#pragma pack(1)
struct testStruct {
// Word 0 (desired)
unsigned a : 8;
unsigned b : 1;
bool c : 1;
unsigned d : 21;
bool e : 1;
// Word 1 (desired)
int f : 32;
// Words 2-3 (desired)
int g[2]; //Cannot assign bit field but takes 64 bits in my compiler
};
testStruct test; …Run Code Online (Sandbox Code Playgroud) bit-fields ×3
c++ ×2
boolean ×1
c11 ×1
c99 ×1
compiler-bug ×1
gcc ×1
pack ×1
pragma ×1
struct ×1