规则(以结构为例):
1、数据成员对齐规则:
第一个数据成员放在offset为0的地方,
以后每个数据成员的对齐按照#pragma pack指定的数值和这个数据成员自身长度中,比较小的那个进行。
解释:
何为对齐:即数据成员相对于结构的首地址的偏移量(以字节为单位)是对齐模数的整数倍
何为对齐模数:#pragma pack指定的数值和数据成员自身长度(字节为单位)中,较小值
2、整体对齐规则:
在数据成员完成各自对齐之后,结构本身也要进行对齐,
对齐将按照#pragma pack指定的数值和最大数据成员中,比较小的那个进行。
解释:
何为对齐:结构的整体长度是整体对齐模数的整数倍
何为整体对齐模数:#pragma pack指定的数值和最大数据成员长度(以字节为单位)中,较小值
3、结合1、2推断:
当#pragma pack指定的数值等于或超过所有数据成员长度的时候,这个值的大小将不产生任何效果。
4、如果没有#pragma pack指令,
相当于#pragma pack指定的数值无限大(即上述规则1、2,对齐模数不用考虑#pragma pack,只需要考虑数据成员自身和结构本身)
考虑位域
如果结构体中含有位域(bit-field),那么VC中准则是:
1、如果相邻位域字段的类型相同,且其位宽之和小于(前一个字段的)类型的大小(以位为单位),
则后面的字段将紧邻前一个字段存储(相当于丢弃后一个字段的类型,存储在上一个字段的类型字节里);
2、如果相邻位域字段的类型相同,但其位宽之和大于类型的大小,则后面的字段将从新的类型开始(即存储在自己的类型字节里);
3、如果相邻的位域字段的类型不同,则各编译器的具体实现有差异,
VC6采取不压缩方式(不同位域字段存放在不同的位域类型字节中),Dev-C++和GCC都采取压缩方式;
4、如果位域字段之间穿插着非位域字段,则不进行压缩;
5、如果存在空域,空域后的字段必须存储在自己的类型字节中。空域和前一个非空域所占大小=二者中较大的类型的大小
5、位域的类型(压缩之后剩下的类型)也需要遵循内存对齐。
1、数据成员对齐规则:
第一个数据成员放在offset为0的地方,
以后每个数据成员的对齐按照#pragma pack指定的数值和这个数据成员自身长度中,比较小的那个进行。
解释:
何为对齐:即数据成员相对于结构的首地址的偏移量(以字节为单位)是对齐模数的整数倍
何为对齐模数:#pragma pack指定的数值和数据成员自身长度(字节为单位)中,较小值
2、整体对齐规则:
在数据成员完成各自对齐之后,结构本身也要进行对齐,
对齐将按照#pragma pack指定的数值和最大数据成员中,比较小的那个进行。
解释:
何为对齐:结构的整体长度是整体对齐模数的整数倍
何为整体对齐模数:#pragma pack指定的数值和最大数据成员长度(以字节为单位)中,较小值
3、结合1、2推断:
当#pragma pack指定的数值等于或超过所有数据成员长度的时候,这个值的大小将不产生任何效果。
4、如果没有#pragma pack指令,
相当于#pragma pack指定的数值无限大(即上述规则1、2,对齐模数不用考虑#pragma pack,只需要考虑数据成员自身和结构本身)
考虑位域
如果结构体中含有位域(bit-field),那么VC中准则是:
1、如果相邻位域字段的类型相同,且其位宽之和小于(前一个字段的)类型的大小(以位为单位),
则后面的字段将紧邻前一个字段存储(相当于丢弃后一个字段的类型,存储在上一个字段的类型字节里);
2、如果相邻位域字段的类型相同,但其位宽之和大于类型的大小,则后面的字段将从新的类型开始(即存储在自己的类型字节里);
3、如果相邻的位域字段的类型不同,则各编译器的具体实现有差异,
VC6采取不压缩方式(不同位域字段存放在不同的位域类型字节中),Dev-C++和GCC都采取压缩方式;
4、如果位域字段之间穿插着非位域字段,则不进行压缩;
5、如果存在空域,空域后的字段必须存储在自己的类型字节中。空域和前一个非空域所占大小=二者中较大的类型的大小
5、位域的类型(压缩之后剩下的类型)也需要遵循内存对齐。
实际计算时,先考虑位域操作(即参照规则1进行压缩),再考虑内存对齐,比较方便。
实例:
参考:
http://www.cnblogs.com/kevinLee-xjtu/archive/2011/12/12/2299090.html
http://baike.baidu.com/view/1256879.htm