現代電腦記憶體以位元組編址,理論上可從任意位址存取任意型別。但硬體平台常要求特定型別只能從特定位址存取(如 4 位元組 int 需 4 的倍數位址)。違反對齊會導致:
這是空間(填充位元組)與時間(存取速度)的博弈。
一般情況編譯器自動處理。可用 #pragma pack(value) 指定最大對齊值(1/2/4/8/16),#pragma pack() 恢復預設。
char=1, short=2, int/float/double=4(32 位系統,64 位下 double/指標常為 8)。#pragma pack(n) 的 n,未指定時為編譯器預設(通常 4 或 8)。min(自身對齊值, 指定對齊值)。決定成員實際存放位址:位址 % 有效對齊值 == 0。{int a; char b; short c;}sizeof=8(尾部填充 1 位元組對齊結構體自身)。{char b; int a; short c;}b @0 (對齊 1)。a 需 4 對齊,@4~7(填充 3 位元組 @1~3)。c 需 2 對齊,@8~9。sizeof=12。#pragma pack(2) {char b; int a; short c;}b@0, a 有效對齊 min(4,2)=2 → @2~5, c@6~7。sizeof=8。#pragma pack(1) → sizeof=7(無填充)。不同平台(Win/Linux、32/64 位、不同編譯器)預設對齊可能不同。傳輸結構體二進位資料時,雙方必須显式約定相同 #pragma pack 設定,否則解析錯誤極難排查。
#pragma pack 並加註解。offsetof、alignof (C11) 靜態斷言驗證佈局。掌握對齊演算法,能精準預測 sizeof、避免跨平台資料互操作陷阱、編寫高效能系統程式碼。