#pragma pack ディレクティブは、このディレクティブの後に続く構造体のメンバーに適用される現行の位置合わせ規則を変更します。
ここで、
1 | 2 | 4 | 8 | 16 構造体のメンバーは、指定したバイト位置合わせ、または自然な位置合わせ境界のいずれか少ない方で位置合わせされ、指定された値はスタックにプッシュされます。 nopack パッキングは適用されず、パック・スタックには "nopack" がプッシュされます。 pop プラグマ・パック・スタックの一番上のエレメントがポップされます。 (引き数の指定なし) #pragma pack() の指定は、 #pragma pack(pop) の指定と同じ効果があります。
#pragma pack ディレクティブは、このディレクティブの後に続けて宣言される構造体のメンバーについてのみ、現行の位置合わせ規則を変更します。これにより、構造体の位置合わせが直接、影響を受けることはありませんが、構造体のメンバーの位置合わせに影響が生ずることにより、位置合わせ規則に従って構造体全体の位置合わせが影響を受ける場合があります。
#pragma pack ディレクティブでは、メンバーの位置合わせを強化することはできず、むしろ位置合わせを低下させる可能性があります。例えば、整数データ型 (int) のメンバーの場合、#pragma pack(2) ディレクティブでは、当該メンバーは構造体内で 2 バイト境界でパックされますが、#pragma pack(4) ディレクティブでは有効ではありません。
#pragma pack ディレクティブは、スタックをベースにしています。すべてのパック値は、ソース・コードの構文解析時にスタックにプッシュされます。現行のプラグマ・パック・スタックの一番上にある値が、現行の位置合わせ規則のスコープ内の後続のすべての構造体のメンバーをパックするために使用されます。
#pragma pack スタックは、位置合わせ規則スタック内の現行エレメントに関連付けられます。位置合わせ規則は、-qalign コンパイラー・オプションまたは #pragma options align ディレクティブで指定します。新規の位置合わせ規則が作成されると、新規 #pragma pack スタックが作成されます。現行の位置合わせ規則がポップされて、位置合わせ規則スタックから外された場合、現行の #pragma pack スタックは空になり、直前の #pragma pack スタックが復元されます。スタック操作 (パック設定のプッシュおよびポップ) は、現行の #pragma pack スタックにのみ影響します。
#pragma pack ディレクティブは、ビット・フィールドがビット・フィールド・コンテナー境界をクロスする原因となります。
struct s_t1 { char a; int b; #pragma pack(1) struct s_t2 { char x; int y; } S2; char c; int d; } S1;
struct s_t { char a; int b; short c; int d; }S;
デフォルト・マッピング: #pragma pack(1): sizeof s_t = 16 sizeof s_t = 11 offsetof a = 0 offsetof a = 0 offsetof b = 4 offsetof b = 1 offsetof c = 8 offsetof c = 5 offsetof d = 12 offsetof d = 7 align of a = 1 align of a = 1 align of b = 4 align of b = 1 align of c = 2 align of c = 1 align of d = 4 align of d = 1