以下在vc6.0和gcc中测试。
废话少说,马上开始。
struct test{
char tmaclub;
int luyi;
short lu;
};
如果不考虑对齐策略,char占1字节,int 4字节,short 2字节,共7字节,但在vc上测试为12字节,其中分别占了4个字节。why??
先看几条原则:
原则1、普通数据成员对齐规则:第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小的整数倍开始。(例子中,char先占一字节,int在32位机为4字节,则要从4的整数倍地址开始存储,所以导致char后面要填充3个字节,以满足原则1)。
原则2、结构体成员对齐规则:如果一个结构里有某些结构体成员,则该结构体成员要从其内部最大元素大小的整数倍地址开始存储。(struct a里存有struct b,b里有char,int,double等元素,那b应该从、8的整数倍开始存储)由简入繁,后面会举个例子证明。
原则3、结构体大小对齐规则:结构体大小也就是sizeof的结果,必须是其内部成员中最大的对齐参数的整数倍,不足的要补齐。(short应该占2字节,原则3要求后面必须补齐)
struct test1{
char tmaclub;
struct test a;
int luyi;
short lu;
}
现在稍微复杂了,test1结构应该占多少呢?这设计到了原则2,原则2决定了变量a必须从地址为4的倍数的地方开始存储。所以变量分布为:4+12+4+4=24。应该很清楚了。
struct test{
char tmaclub;
double tmac;
int luyi;
short lu;
};
由以上推断此结构体应占24(8+8+4+4)字节,事实也确实如此。但以上都是在vc的结果,在gcc上测试得出的结论应该为20(4+8+4+4)。可见这是编译器相关的。在gcc中,第一条规则需要修改为“以后每个数据成员存储的起始地址要从min(成员本身大小,4)的整数倍开始”,这样就对了。
严格一点说应该是:Win32平台下的微软VC编译器在默认情况下采用如下的对齐规则: 任何基本数据类型T的对齐模数就是T的大小,即sizeof(T)。比如对于double类型(8字节),就要求该类型数据的地址总是8的倍数,而char类型数据(1字节)则可以从任何一个地址开始。。Linux下的GCC奉行的是另外一套规则:对齐模数应该是4和它本身中的较小者。
以上经过测试,如有笔误,敬请谅解。
阅读(1579) | 评论(0) | 转发(0) |