包含位域的结构的大小在不同的编译器上是不同的

我在VS和GCC上运行了以下程序。

#include  int main(void) { struct bitfield { unsigned a : 3; char b; unsigned c : 5; int d; }bit; printf("Size = %d\n", sizeof(bit)); return 0; } 

令我惊讶的是,VS给出16作为sizeof结构,GCC给出12。

我的理解是编译器尝试在1行(Bank0,Bank1,Bank2,Bank3)中分配achar bc ,在另一行中分配int d 。 这似乎表明结构的大小应该是8个字节(假设是32位系统)。

谁能解释这些结果? 我在64位机器上运行。

编译器只需要将在结构中相邻声明的位字段打包到相同的“可寻址存储单元”(在这种情况下,给定32位CPU,这可能是32位的块)。 您在它们之间显示了一个char,因此编译器可以随意分配您的结构。

通常,标准字段的位置非常差,因此完全不可移植且不可预测。 未指定位分配的顺序。 没有指定哪个位是MSB。 未指定对齐。 没有指定位字段是否可以“跨越”“存储单元”。 等等。

此外,struct可以在任何地方包含填充字节。

更好的想法是永远不要使用位字段,而是使用按位运算符。

由于您的系统具有64位架构,因此大多数编译器将以8字节填充。
Gcc目前的版本仍然填充4个字节。
此外,结构填充完全取决于编译器。 你会在’c’代码中看到许多未定义的行为,比如使用一元增量(前/后),填充,内存映射等,这完全是编译器和m / c相关的。 所以,实际上没有这样的解释。
另外,在您的系统上运行以下代码。 在这种情况下,VS应该是o / p 24和GCC 16。

 #include  int main(void) { struct bitfield { unsigned a : 3; unsigned c : 5; int d; char b; }bit; printf("Size = %d\n", sizeof(bit)); return 0; }