Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么与混合数据类型的位字段相比,相同数据类型的位字段的大小更小_C++_C_Bit Fields - Fatal编程技术网

C++ 为什么与混合数据类型的位字段相比,相同数据类型的位字段的大小更小

C++ 为什么与混合数据类型的位字段相比,相同数据类型的位字段的大小更小,c++,c,bit-fields,C++,C,Bit Fields,我很想知道为什么具有相同数据类型的位字段比具有混合数据类型的位字段占用更少的大小 数据类型 struct xyz { int x : 1; int y : 1; int z : 1; }; struct abc { char x : 1; int y : 1; bool z : 1; }; sizeof(xyz)=4 sizeof(abc)=12 我使用的是VS2005,64位x86机器 位机/编译器级别的答案会很好。对齐 您的编译器将以适合

我很想知道为什么具有相同数据类型的位字段比具有混合数据类型的位字段占用更少的大小 数据类型

struct xyz 
{ 
  int x : 1; 
  int y : 1; 
  int z : 1; 
}; 


struct abc 
{ 
  char x : 1; 
  int y : 1; 
  bool z : 1; 
}; 
sizeof(xyz)=4 sizeof(abc)=12

我使用的是VS2005,64位x86机器

位机/编译器级别的答案会很好。

对齐

您的编译器将以适合您的体系结构的方式对齐变量。在您的例子中,
char
int
bool
是不同的大小,因此它将根据该信息而不是您的位字段提示

对这件事进行了一些讨论

解决方案是向编译器提供
#pragma
指令或
uu属性uu
,以指示编译器忽略对齐优化。

C标准(1999版,§6.7.2.1,第102页,第10点)规定:

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

似乎没有任何措辞允许包装受字段类型的影响。因此,我认为这是一个编译器错误


在Linux下,gcc在32位和64位机器上都会生成一个4字节的结构。我没有VS,无法测试。

这是编译器错误或某些代码错误。 结构中分配的所有位始终尝试定义最高数据类型的大小。 e、 g.在结构xyz中,最大数据类型的大小为4,即int。 对于第二个结构,abc的最高数据类型大小与int的相同,为4

其中,似乎我们改变了结构变量,如下所示: 结构abc { 字符a:1; 字符b:1; boolc:1; };

sizeof(abc)将是1而不是4。因为大小最高的数据类型是1,所有的位都适合1字节的字符

可以通过更改结构中的数据类型来执行各种测试

基于旧结构的输出链接: 拜访

基于我定义的上述结构的输出链接: 拜访


为避免结构大小出现此类问题,我们应使用#pragma pack宏正确打包结构。

注意,位字段实际上没有对齐要求。没有,但编译器没有义务打包。请参阅ISO14882:2003,§9.6,第1段。尽管SO.C++03,§9.6,第1段中有人否认学习机器体系结构和编译器构造对程序员仍然有用的另一个原因,“类对象中位字段的分配由实现定义。位字段的对齐由实现定义。位字段被打包成一些可寻址的分配单元。“看来MaHash正在使用C++编译器。另一方面,他还把这个标记为C问题,而不仅仅是C++。我猜C和C++的答案是不同的。我会谨慎地称这是一个错误。“因为您引用的是ISO C99标准。MSVC++没有声明遵守C99。它支持ISO C90/ANSI C89.PS:在位字段中使用int或unsigned以外的类型是对C89/90的扩展,因此所有关于行为的赌注都是无效的。如果MSVC++不支持十年前的标准。。。听起来不太令人印象深刻,是吗?