C语言中的对齐方式#pragma pack()伪指令及_attribute_aligned_指令

Q:为什么会引入这样的伪指令呢?

A:我们知道,在存储结构体或联合(struct / union)这样的复合型变量时,计算机在内存空间中开辟一段连续的位置,按照成员变量定义的自然顺序进行初始化。但是往往结构体中的不同成员变量类型各异,存储起来其空间大小必然不一样。在程序处理过程中,计算机的PC指针按照怎样的方式对成员变量进行访问,取决于其存储时存储空间的分配方式。

例如,对结构体:
struct _struct{
     int a;
     char b;
     float c;
}A;


 
   
显然可以有如下几种方式进行存储空间的开辟:
C语言中的对齐方式#pragma pack()伪指令及_attribute_aligned_指令_第1张图片
对上图的解释为:
fig.a中的开辟方式,PC指针操作每个成员变量时,按照类似数组寻址的方式进行访问,简单;后两者中的方式,需要对变量进行判断或需要一个额外的累加寄存器。
#pragma pack(N) 伪指令用来强制编译器在对结构体或联合进行初始化时在存储空间的对齐方式:按照N字节对齐;
#pragma pack() 表示如果在编译到此处之前,已经配置过#pragma pack(N),则在该语句之后取消强制设置,按照默认方式进行对齐。
例如有如下结构体:
struct _struct{
     int a;
     char b;
}A;

因为 sizeof(int) > sizeof(char):
(1) 在未使用伪指令进行配置时,sizeof(A)=2max(sizeof(int),sizeof(char))=2sizeof(int)=8;
(2) 如果使用:#pragma pack(4),或者#pragma pack(6)等,因为结构体中最大的成员变量字节为4,故按照默认方式对齐;
(3) 如果使用:#pragma pack(3),那么,sizeof(A)=max(sizeof(int),3)+max(sizeof(char),3)=4+3=7;
(4) 如果使用:#pragma pack(1),那么,sizeof(A)=max(sizeof(int),3)+max(sizeof(char),3)=4+1=5;

[注意!]
如果#pragma pack(N)中N的大小超过了结构体或联合中成员变量所占字节的最大值,按照默认的方式进行处理(因为如果按照变量个数×单个变量最大字节的大小已经足够存储一个结构体变量,无须浪费更多空间了)。


另外,在GNU C中还有一个__attribute__ ((aligned (N)))   指令,可以达到类似的效果。
其详情可以参考cnbyl123的博客。

你可能感兴趣的:(C语言)