すべての集合体メンバーの位置合わせを、指定したバイト境界に設定する。
バイト境界の数がメンバーの自然な位置合わせよりも小さい場合は、埋め込みバイトが除去されるので、全体的な構造体または共用体のサイズが減少します。
デフォルトの #pragma pack 構文 >>-#--pragma--pack--(--+--------+--)--------------------------->< +-nopack-+ +-number-+ '-pop----'
集合体 (構造体、共用体、およびクラス) のメンバーが自然な境界に位置合わせされ、構造体はその自然な境界上で終わります。集合体の位置合わせは、最も厳密なメンバー (最大の位置合わせ要件を持つメンバー) の位置合わせです。
#pragma pack ディレクティブは、集合体型のインスタンスの宣言よりも、集合体型の定義に適用されます。そのため、指定したタイプの宣言された変数のすべてに自動的に適用されます。
#pragma pack ディレクティブは、このディレクティブの後に続く宣言を持つ構造体のメンバーのみに適用される現行の位置合わせ規則を変更します。 これにより、構造体の位置合わせに直接、影響することはありませんが、 構造体のメンバーの位置合わせに影響することで、 構造体全体の位置合わせに影響する場合があります。
#pragma pack ディレクティブでは、 メンバーの位置合わせを強化することはできず、 むしろ位置合わせを低下させる可能性があります。 例えば、短整数データ型のメンバーの場合、#pragma pack(1) ディレクティブでは、 当該メンバーは構造体内で 1 バイト境界でパックされますが、 #pragma pack(4) ディレクティブでは有効ではありません。
#pragma pack(2)
struct A{
int a:31;
int b:2;
}x;
int main(){
printf("size of S = %d¥n", sizeof(s));
}
When compiled and run, the output is:
size of S = 6
But if you remove the #pragma pack directive, you get this output:
size of S = 8
#pragma pack(1)
struct S;
#pragma pack(4)
struct S { int i, j, k; };
#pragma pack (4) // 4-byte alignment
struct nested {
int x;
char y;
int z;
};
#pragma pack(1) // 1-byte alignment
struct packedcxx{
char a;
short b;
struct nested s1; // 4-byte alignment
};
複数の #pragma pack ディレクティブが、インライン化された関数で定義された構造体に現れる場合は、構造体の先頭で有効な #pragma pack ディレクティブが優先されます。
// header file file.h
#pragma pack(1)
struct jeff{ // this structure is packed
short bill; // along 1-byte boundaries
int *chris;
};
#pragma pack(pop) // reset to previous alignment rule
// source file anyfile.c
#include "file.h"
struct jeff j; // uses the alignment specified
// by the pragma pack directive
// in the header file and is
// packed along 1-byte boundaries
struct s_t {
char a;
int b;
short c;
int d;
}S;
| デフォルト・マッピング: | #pragma pack(1): |
|---|---|
| s_t のサイズは 16 | s_t のサイズは 11 |
| a のオフセットは 0 | a のオフセットは 0 |
| b のオフセットは 4 | b のオフセットは 1 |
| c のオフセットは 8 | c のオフセットは 5 |
| d のオフセットは 12 | d のオフセットは 7 |
| a の位置合わせは 1 | a の位置合わせは 1 |
| b の位置あわせは 4 | b の位置合わせは 1 |
| c の位置合わせは 2 | c の位置合わせは 1 |
| d の位置合わせは 4 | d の位置合わせは 1 |
union uu {
short a;
struct {
char x;
char y;
char z;
} b;
};
union uu nonpacked[2];
共用体メンバーの中では位置合わせに関する最大の要件が short a、つまり 2 バイトの要件なので、埋め込みの 1 バイトが配列中の各共用体の終わりに追加され、この要件を強制します。 ┌───── nonpacked[0] ─────────── nonpacked[1] ───┐
│ │ │
│ a │ │ a │ │
│ x │ y │ z │ │ x │ y │ z │ │
└─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘
0 1 2 3 4 5 6 7 8
次の例では、#pragma pack(1) を使用して、タイプ uu の共用体の位置合わせを 1 バイトに設定しています。 #pragma pack(1)
union uu {
short a;
struct {
char x;
char y;
char z;
} b;
};
union uu pack_array[2];
┌─── packed[0] ───┬─── packed[1] ───┐
│ │ │
│ a │ │ a │ │
│ x │ y │ z │ x │ y │ z │
└─────┴─────┴─────┴─────┴─────┴─────┘
0 1 2 3 4 5 6