您的位置:首页 > 其它

sizeof,真正终结版GCC与VC

2014-01-03 19:49 127 查看
在VC6.0中sizeof结果是16.我电脑上装了个linux虚拟机,在虚拟机上GCC中结果是12,

恩不同编译器默认对齐数值不一样。 VC 默认为 8 gcc 默认为 4 有个编译参数控制对齐。 #pragma pack(4) 加上这个,对齐应该一样了。

VC和GCC默认的都是4字节对齐,编程中可以使用#pragma pack(n)指定对齐模数。出现以上差异的原因在于,VC和GCC中对于double类型的对齐方式不同。
Win32平台下的微软VC编译器在默认情况下采用如下的对齐规则: 任何基本数据类型T的对齐模数就是T的大小,即sizeof(T)。
比如对于double类型(8字节),就要求该类型数据的地址总是8的倍数,而char类型数据(1字节)则可以从任何一个地址开始。
Linux下的GCC奉行的是另外一套规则:任何2字节大小(包括单字节吗?)的数据类型(比如short)的对齐模数是2,而其它所有超过2字节的数据类型(比如long,double)都以4为对齐模数。
复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度。 struct{char a;double b;}
在VC中,因为结构中存在double和char,按照最长数据类型对齐,char只占1B,但是加上后面的double所占空间超过8B,所以char独占8B;而double占8B,一共16Byte。
在GCC中,double长度超过4字节,按照4字节对齐,原理同上,不过char占4字节,double占两个4字节,一共12Byte。
http://zhidao.baidu.com/link?url=iWrBy6yXFRy-vXDmtX3HWVJF7GYVFciWUZHNywJJlUeCGBsBSr32nc5OY2B22mCArHml49fUk-dKxqfAtustVa


原帖由 scutan 于 2007-6-28 14:04 发表
#include<stdio.h>

struct A
{
double l;
int i;
int b;
char c;
};

int main()
{
struct A m[2];
printf("%d\n", sizeof(struct A));
pri ...
[code]http://bbs.chinaunix.net/thread-955085-1-1.html 每个特定平台上的编译器都有自己的默认“对齐系数”(也叫对齐模数)。程序员可以通过预编译命令#pragma pack(n),n=1,2,4,8,16来改变这一系数,其中的n就是你要指定的“对齐系数”。在lz的程序中,n默认是4。 在这个前提下分析lz得到的结果: 4字节对齐(#pragma pack(4)) sizeof(m[0]) = 20; 分析过程: 1)成员数据对齐 struct A { double l; /* 长度8 > 4 按4对齐;起始offset=0 0%4=0;存放位置区间[0,7] */ int i; /* 长度4 = 4 按4对齐;起始offset=8 8%4=0;存放位置区间[8,11] */ int b; /* 长度4 = 4 按4对齐;起始offset=12 12%4=0;存放位置区间[12,15] */ char c; /* 长度 1 = 4 按1对齐;起始offset=16 16%1=0;存放位置区间[16] */ }; 成员总大小为17, 整体对齐系数=min(max (double, int, char), 4) = 4; 整个结构体的大小=20,为什么不是上面算出来的17呢?这里涉及到一个叫做“圆整”的概念。 什么叫“圆整”?比如在这个例子,从17开始,看看那个位置可以被“整体对齐系数(4)”整除,17,18,19都不合适,所以到20,圆整结束。 这也解释了为什么第二个结构体开始的位置不能被8整除,其实只要个能被4整除就可以了。 http://blog.csdn.net/ehui928/article/details/546391
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: