1. 程式人生 > >C語言中的對齊方式#pragma pack()偽指令及_attribute_aligned_指令

C語言中的對齊方式#pragma pack()偽指令及_attribute_aligned_指令

Q:為什麼會引入這樣的偽指令呢? A:我們知道,在儲存結構體或聯合(struct / union)這樣的複合型變數時,計算機在記憶體空間中開闢一段連續的位置,按照成員變數定義的自然順序進行初始化。但是往往結構體中的不同成員變數型別各異,儲存起來其空間大小必然不一樣。在程式處理過程中,計算機的PC指標按照怎樣的方式對成員變數進行訪問,取決於其儲存時儲存空間的分配方式。 例如,對結構體:
struct _struct{
     int a;
     char b;
     float c;
}A;


顯然可以有如下幾種方式進行儲存空間的開闢: 對上圖的解釋為: 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)))   指令,可以達到類似的效果。