1、前言:《***软件编程规范》中提到:“在定义结构数据类型时,为了提高系统效率,要注意4字节对齐原则……”。本文解释x86上字节对齐的机制,其他架构读者可自行试验。同时,本文对C/C++的函数调用方式进行了讨论。BTW想了几天要在休息时间写个总结但是直到今天18日才动手。写出来应该对自己还是有帮助的。也许还有一点点参考价值吧。由于本人水平所限,有不正确之处,欢迎大家提出。感谢几位同事。以及carrot。呵呵……下面言归正传。1.先看下面的例子:struct A{ char c1; int i; short s; int j;}a;struct B{ int i; int
2、j; short s; char c1;}b;结构A没有遵守字节对齐原则(为了区分,我将它叫做对齐声明原则),结构B遵守了。我们来看看在x86上会出现什么结果。先打印出a和b的各个成员的地址。会看到a中,各个成员间的间距是4个字节。b中,i和j,j和s都间距4个字节,但是s和c1间距2个字节。所以:sizeof(a) = 16sizeof(b) = 12为什么会有这样的结果呢?这就是x86上字节对齐的作用。为了加快程序执行的速度,一些体系结构以对齐的方式设计,通常以字长作为对齐边界。对于一些结构体变量,整个结构要对齐在内部成员变量最大的对齐边界,如B,整个结构以4为对齐边界
6、式声明2) 对于逻辑上相关的成员变量希望放在靠近的位置,就写成A的方式。有一种做法是显式的插入reserved成员: struct A{ char c1; char reserved1[3]; int i; short s; char reserved2[2]; int j;}a;3) 随便怎么写,一切交给编译器自动对齐。代码中关于对齐的隐患,很多是隐式的。比如在强制类型转换的时候。下面举个例子:unsigned int ui_1=0x
7、12345678;unsigned char *p=NULL;unsigned short *us_1=NULL;p=&ui_1;*p=0x00;us_1=(unsigned short *)(p+1);*us_1=0x0000;最后两句代码,从奇数边界去访问unsigned short型变量,显然不符合对齐的规定。在x86上,类似的操作只会影响效率,但是在MIPS或者sparc上,可能就是一个bus error(我没有试)。有些人喜欢通过移动指针来操作结构中的成员(