pragma pack 結構體對齊編譯器選項

2021-08-07 10:17:49 字數 1469 閱讀 7834

現代計算機中記憶體空間都是按照byte劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何位址開始,但是各個硬體平台對儲存空間的處理上有很大的不同。一些平台對某些特定型別的資料只能從某些特定位址開始訪問。其他平台可能沒有這種情況,但是如果不按照適合其平台要求對資料存放進行對齊,會在訪問效率上帶來損失。舉個例子:有些平台每次讀都是從偶位址開始,如果乙個int型(假設為32位系統)如果存放在偶位址開始的地方,那麼乙個讀週期就可以讀出,而如果存放在奇位址開始的地方,就可能會需要2個讀週期,並對兩次讀出的結果的高低位元組進行拼湊才能得到該int資料。顯然在讀取效率上下降很多。這也是空間和時間的博弈。

一般來說,我們寫程式的時候,不需要考慮對齊問題。編譯器會替我們選擇適合目標平台的對齊策略。當然,我們也可以通過預編譯指令改變對指定資料的對齊方法,正是因為編輯器對資料存放做了對齊,而我們不了解的話,常常會對一些問題感到迷惑。最常見的就是struct資料結構所佔位元組大小結果。

#include 

typedef

struct _pack_test

pack_test;

int main()

編譯執行結果:

sizeof(pack_test)=8
由於編譯器的對齊,結構體pack_test所佔位元組大小為8,而不是sizeof(int)+sizeof(char)=5。

通過#pragma pack指令可以人為指定資料的對齊方法,常用的#pragma pack指令有以下幾種:

#pragma pack(n)             /* c編譯器將按照n位元組對齊 */

#pragma pack() /* 作用:取消自定義位元組對齊方式,恢復預設的位元組對齊方式 */

#pragma pack(push,n) /* 作用:把現有對齊方式設定壓棧,並設新的對齊方式設定為n位元組對齊 */

#pragma pack(pop) /* 作用:恢復之前的對齊方式 */

下面這個例子展示了#pragma pack指令的用法:

#include 

#pragma pack(push,1)

typedef

struct _pack_test

pack_test;

#pragma pack(pop)

typedef

struct _no_pack_test

no_pack_test;

int main()

編譯執行結果:

sizeof

(pack_test)=5

sizeof

(no_pack_test)=8

注意:可以看到改變資料型別的對齊方式,直接效果就是資料型別占用記憶體的減少,但是效能會下降,一般來說,我們不會主動改變資料型別的對齊方式。

結構體對齊的具體含義( pragma pack)

結構體對齊的具體含義 pragma pack 現在去掉第乙個成員變數為如下 pragma pack 4 class testc int nsize sizeof testc 按照正常的填充方式nsize的結果應該是8,為什麼結果顯示nsize為6呢?事實上,很多人對 pragma pack的理解是錯...

結構體對齊的具體含義( pragma pack)

結構體對齊的具體含義 pragma pack 朋友帖了如下一段 pragma pack 4 class testb int nsize sizeof testb 這裡nsize結果為12,在預料之中。現在去掉第乙個成員變數為如下 pragma pack 4 class testc int nsize...

結構體對齊的具體含義( pragma pack)

panic2005年4月2日 現在去掉第乙個成員變數為如下 pragma pack 4 class testc int nsize sizeof testc 按照正常的填充方式nsize的結果應該是8,為什麼結果顯示nsize為6呢?事實上,很多人對 pragma pack的理解是錯誤的。pragm...