C 包含位字段的结构的大小在不同的编译器上是不同的
我在VS和GCC上运行了下面的程序C 包含位字段的结构的大小在不同的编译器上是不同的,c,visual-studio,gcc,C,Visual Studio,Gcc,我在VS和GCC上运行了下面的程序 #include <stdio.h> int main(void) { struct bitfield { unsigned a : 3; char b; unsigned c : 5; int d; }bit; printf("Size = %d\n", sizeof(bit)); return 0; } #包括 内部主(空) { 结构
#include <stdio.h>
int main(void)
{
struct bitfield
{
unsigned a : 3;
char b;
unsigned c : 5;
int d;
}bit;
printf("Size = %d\n", sizeof(bit));
return 0;
}
#包括
内部主(空)
{
结构位域
{
未签名a:3;
字符b;
无符号c:5;
int d;
}比特;
printf(“大小=%d\n”,大小(位));
返回0;
}
令我惊讶的是,VS给出16作为sizeof
结构,GCC给出12
我的理解是,编译器试图将a
、char b
和c
分配到一行(Bank0、Bank1、Bank2、Bank3),并将int d
分配到另一行。这似乎表明结构的大小应该是8字节(假设是32位系统)
有人能解释这些结果吗?我在64位计算机上运行。由于您的系统具有64位体系结构,大多数编译器将以8字节填充。
Gcc在其当前版本中仍然填充4个字节
此外,结构填充完全依赖于编译器。在“c”代码中有许多未定义的行为,比如使用一元增量(pre/post)、填充、内存映射等,这些行为完全依赖于编译器和m/c。因此,实际上没有这样的解释。
另外,在系统上运行以下代码。在这种情况下,VS应为o/p 24和GCC 16
#include <stdio.h>
int main(void)
{
struct bitfield
{
unsigned a : 3;
unsigned c : 5;
int d;
char b;
}bit;
printf("Size = %d\n", sizeof(bit));
return 0;
}
#包括
内部主(空)
{
结构位域
{
未签名a:3;
无符号c:5;
int d;
字符b;
}比特;
printf(“大小=%d\n”,大小(位));
返回0;
}
编译器只需将结构中相邻声明的位字段打包到同一个“可寻址存储单元”(给定32位CPU,在本例中可能是32位的块)。您在它们之间显示了一个字符,因此编译器可以随意分配结构
通常,标准对位字段的规定非常糟糕,因此完全不可移植且不可预测。未指定位的分配顺序。未指定哪个位是MSB。未指定对齐方式。未指定位字段是否“跨”于“存储单元”。等等
此外,结构可以在任何位置包含填充字节
更好的办法是根本不使用位字段,而是使用按位运算符。首先,告诉我编译器上sizeof(int)的o/p我觉得它将是8,而不是4(如您所预期),因为m/c是64位的,编译器也是64位的。这取决于编译器。对于VS可能会有所帮助。对于如何填充此结构,您确实无法做出任何假设。在这方面,每个编译器都可以自由地做任何事情,只要元素都正确对齐并且顺序正确。