总能够网上搜到这样的,关于结构体sizeof的答案,然而,经过这个简单的实验以后,发现gcc5.3编译的结果并非如此。
字节对齐的细节和具体编译器实现相关,但一般而言,满足三个准则:
1. 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
2. 结构体每个成员相对于结构体首地址的偏移量都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节;
3. 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节。
#include <stdio.h> typedef unsigned char U8; typedef unsigned short U16; typedef unsigned int U32; typedef unsigned long long U64; typedef struct type1{ U8 size8; U32 size32; U16 size16; }type1; typedef struct type2{ U8 size8; U16 size16; U32 size32; }type2; int main(int argc, char * argv[]){ U8 size8; U16 size16; U32 size32; U64 size64; printf("U8:%d, U16:%d, U32:%d, U64:%d ", sizeof(size8), sizeof(size16), sizeof(size32), sizeof(size64)); printf("type1:%d type2:%d ", sizeof(type1), sizeof(type2)); return 0; }
输出结果如下:
U8:1, U16:2, U32:4, U64:8 type1:12 type2:8
结论:
在GCC(暂时仅限于5.3版本的测试)中,C语言(未测试C++情况)结构体的长度有如下规则:
1.结构体的偏移量为结构体中最宽基本类型成员大小;
2.结构体的总大小为结构体偏移量的整数倍;
1&2 => 结构体的总大小为结构体最宽基本类型成员大小的整数倍;
3.结构体的每一个成员会按照结构体的位置排布,当遇到其中成员的长度不是偏移量的整数倍时,编译器(gcc5.3)会先视该成员的下一个成员的长度,判断是否需要空出(“偏移量”类似与键盘Tab的作用)。