C中结构的大小; GCC 与实际计算
Size of Struct in C; GCC vs Actual Calculation
根据c_faq,
typedef struct {
char a[3];
short int b;
long int c;
char d[3];
} T;
sizeof(T) 将 return 在 32 位 gcc 编译器 上 16。因为对齐是4,所以要计算,我应该这样做:3+(1)+2+(2)+4+3+(1)
,其中括号代表paddings。海湾合作委员会同意。
基于这个逻辑,我又做了一些自己的练习。
typedef struct{
char buf1[9];
unsigned short s;
double d;
char buf2[3];
} S;
sizeof(S) 应该 return 我 32 在 32 位 gcc 编译器 上。因为对齐是8,所以要计算,我应该这样做:8+1+2+(5)+8+3+(5)
。但是,gcc 告诉我 sizeof(S) 是 24。
我认为这是因为优化,然而,在 gcc 中弄乱了 -O0 标志后,sizeof(S) 仍然是 24。
这是怎么回事?
我正在使用这个 gcc -m32 main.c
来编译。
在此先致谢!
编辑 : 所以如果我理解正确的话,我的计算和GCC的计算不匹配的原因是因为每个编译器都有自己处理结构数据的方式。那么计算结构大小的通用方法是什么?或者更确切地说,计算结构大小的原始方法是什么?
Then what is a universal way of calculating the size of a struct? Or rather, what is the original way of calculating the size of a struct?
没有万能的方法。也没有真正的 "original" 方法,因为 C 是在 1970 年代创建的,当时 PDP-11 还很流行,并且直到 1989 年才正式指定 C。它是实现定义的,并且因平台而异(而且我不仅仅是轻率;它确实确实在平台和实现之间有所不同(甚至编译器标志!))。
如果您的教授希望您计算结构的大小,那么他或她必须提供每种数据类型所需的对齐方式。如果他们不这样做,那么他们的问题就没有明确说明(几乎无限数量的不同答案可以被辩护为 "correct")。
我编写了以下代码来检查结构中每个元素的地址。
#include <stdio.h>
typedef struct{
char buf1[9];
unsigned short s;
double d;
char buf2[3];
} S;
int main()
{
S S1;
S *Sptr = &S1;
printf ("\n sizeof (S) is %d",sizeof(S));
printf ("\n Buf1 --> %d",(char*) &(Sptr->buf1[0]) - (char*)Sptr);
printf ("\n s --> %d",(char*) &(Sptr->s) - (char*)Sptr);
printf ("\n d --> %d",(char*) &(Sptr->d) - (char*)Sptr);
printf ("\n Buf2 --> %d",(char*) &(Sptr->buf2[0]) - (char*)Sptr);
return 0;
}
我的编译器(cygwin 64 位)的结果是
sizeof (S) is 32
Buf1 --> 0
s --> 10
d --> 16
Buf2 --> 24
short 位于第 10 个字节,因此它在 2 个字节边界上对齐。 double 位于 16m 处,并在 8 字节边界处对齐。最终结构也被填充为 8 个字节。
根据c_faq,
typedef struct {
char a[3];
short int b;
long int c;
char d[3];
} T;
sizeof(T) 将 return 在 32 位 gcc 编译器 上 16。因为对齐是4,所以要计算,我应该这样做:3+(1)+2+(2)+4+3+(1)
,其中括号代表paddings。海湾合作委员会同意。
基于这个逻辑,我又做了一些自己的练习。
typedef struct{
char buf1[9];
unsigned short s;
double d;
char buf2[3];
} S;
sizeof(S) 应该 return 我 32 在 32 位 gcc 编译器 上。因为对齐是8,所以要计算,我应该这样做:8+1+2+(5)+8+3+(5)
。但是,gcc 告诉我 sizeof(S) 是 24。
我认为这是因为优化,然而,在 gcc 中弄乱了 -O0 标志后,sizeof(S) 仍然是 24。
这是怎么回事?
我正在使用这个 gcc -m32 main.c
来编译。
在此先致谢!
编辑 : 所以如果我理解正确的话,我的计算和GCC的计算不匹配的原因是因为每个编译器都有自己处理结构数据的方式。那么计算结构大小的通用方法是什么?或者更确切地说,计算结构大小的原始方法是什么?
Then what is a universal way of calculating the size of a struct? Or rather, what is the original way of calculating the size of a struct?
没有万能的方法。也没有真正的 "original" 方法,因为 C 是在 1970 年代创建的,当时 PDP-11 还很流行,并且直到 1989 年才正式指定 C。它是实现定义的,并且因平台而异(而且我不仅仅是轻率;它确实确实在平台和实现之间有所不同(甚至编译器标志!))。
如果您的教授希望您计算结构的大小,那么他或她必须提供每种数据类型所需的对齐方式。如果他们不这样做,那么他们的问题就没有明确说明(几乎无限数量的不同答案可以被辩护为 "correct")。
我编写了以下代码来检查结构中每个元素的地址。
#include <stdio.h>
typedef struct{
char buf1[9];
unsigned short s;
double d;
char buf2[3];
} S;
int main()
{
S S1;
S *Sptr = &S1;
printf ("\n sizeof (S) is %d",sizeof(S));
printf ("\n Buf1 --> %d",(char*) &(Sptr->buf1[0]) - (char*)Sptr);
printf ("\n s --> %d",(char*) &(Sptr->s) - (char*)Sptr);
printf ("\n d --> %d",(char*) &(Sptr->d) - (char*)Sptr);
printf ("\n Buf2 --> %d",(char*) &(Sptr->buf2[0]) - (char*)Sptr);
return 0;
}
我的编译器(cygwin 64 位)的结果是
sizeof (S) is 32
Buf1 --> 0
s --> 10
d --> 16
Buf2 --> 24
short 位于第 10 个字节,因此它在 2 个字节边界上对齐。 double 位于 16m 处,并在 8 字节边界处对齐。最终结构也被填充为 8 个字节。