#pragma pack

説明

#pragma pack ディレクティブは、そのディレクティブの後に続く構造体のメンバーの位置合わせ規則を変更します。

構文

構文図を読む構文図をスキップする>>-#--pragma--pack--(--+--------+--)---------------------------><
                       +-nopack-+
                       +-1------+
                       +-2------+
                       +-4------+
                       +-8------+
                       +-16-----+
                       '-pop----'
 

ここで、

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 ディレクティブ ビット・フィールドにビット・フィールド・コンテナーの境界をクロスさせます

  1. 以下に示すコードでは、構造体 s_t2 ではメンバーが 1 バイトにパックされますが、構造体 s_t1 は影響を受けません。この理由は、s_t1 の宣言がプラグマ・ディレクティブよりも前に開始されているためです。しかし、s_t2 はその宣言がプラグマ・ディレクティブよりも後に開始されているため影響を受けます。
    struct s_t1 {
        char a;	
        int b;
        #pragma pack(1)
        struct s_t2 {	
                char x;
                int y;
        } S2;
        char c;
        int d;
    } S1;
  2. この例は、#pragma pack ディレクティブが構造体のサイズとマッピングにどのような影響を与えるかを示したものです。
    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

関連情報