#pragma pack
Category
Purpose
Sets the alignment of all aggregate members to a specified byte boundary.
If the byte boundary number is smaller than the natural alignment of a member, padding bytes are removed, thereby reducing the overall structure or union size.
Syntax
>>-#--pragma--pack--(--+-number-------+--)--------------------->< +-full---------+ +-num:C_Compat-+ +-packed-------+ +-pop----------+ +-twobyte------+ '-reset--------'
Defaults
Members of aggregates (structures, unions, and classes) are aligned on their natural boundaries and a structure ends on its natural boundary. The alignment of an aggregate is that of its strictest member (the member with the largest alignment requirement).
Parameters
- number
- is one of the following:
- 1
- Aligns structure members on 1-byte boundaries, or on their natural alignment boundary, whichever is less.
- 2
- Aligns structure members on 2-byte boundaries, or on their natural alignment boundary, whichever is less.
- 4
- Aligns structure members on 4-byte boundaries, or on their natural alignment boundary, whichever is less.
- 8
- Reserved for possible future use.
- 16
- Reserved for possible future use.
- full
- Aligns structure members on 4-byte boundaries, or on their natural alignment boundary, whichever is less. This is the same as #pragma pack(4).
- num:C_Compat
- num is one of the following:
- 1 (aligns structure members on 1-byte boundaries, or on their natural alignment boundary, whichever is less)
- 2 (aligns structure members on 2-byte boundaries, or on their natural alignment boundary, whichever is less)
num:C_Compat aligns structure members so that the class layout will be compatible with the layout produced by the XL C compiler. This applies when:- You have a class layout that is guarded by #pragma pack(1) or #pragma pack(2).
- Your class data member contains a bit field that has an alignment that exceeds the alignment defined by #pragma pack(1) or #pragma pack(2).
- The bit length of the bit field exceeds the maximum number that the bit field type is allowed to contain.
- packed
- Aligns structure members on 1-byte boundaries, or on their natural alignment boundary, whichever is less. This is the same as #pragma pack(1).
- pop
- Removes the previous value added with #pragma pack. Specifying #pragma
pack() with no parameters is equivalent to specifying #pragma
pack(pop) or #pragma pack(4) .Note: #pragma pack() with no parameters is deprecated. Use #pragma pack(4) instead.
- twobyte
- Aligns structure members on 2-byte boundaries, or on their natural alignment boundary, whichever is less. This is the same as #pragma pack(2).
- reset
- Sets the packing rule to that which was in effect before the current setting.
Usage
The #pragma pack directive applies to the definition of an aggregate type, rather than to the declaration of an instance of that type; it therefore automatically applies to all variables declared of the specified type.
The #pragma pack directive modifies the current alignment rule for only the members of structures whose declarations follow the directive. It does not affect the alignment of the structure directly, but by affecting the alignment of the members of the structure, it may affect the alignment of the overall structure.
The #pragma pack directive cannot increase the alignment of a member, but rather can decrease the alignment. For example, for a member with data type of short, a #pragma pack(1) directive would cause that member to be packed in the structure on a 1-byte boundary, while a #pragma pack(4) directive would have no effect.
size of struct A = 6
size of struct A = 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
};
If more than one #pragma pack directive appears in a structure defined in an inlined function, the #pragma pack directive in effect at the beginning of the structure takes precedence.
Examples
// header file file.h
#pragma pack(1)
struct jeff{ // this structure is packed
short bill; // along 1-byte boundaries
int *chris;
};
#pragma pack(reset) // 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;
Default mapping: | With #pragma pack(1): |
---|---|
size of s_t = 16 | size of s_t = 11 |
offset of a = 0 | offset of a = 0 |
offset of b = 4 | offset of b = 1 |
offset of c = 8 | offset of c = 5 |
offset of d = 12 | offset of d = 7 |
alignment of a = 1 | alignment of a = 1 |
alignment of b = 4 | alignment of b = 1 |
alignment of c = 2 | alignment of c = 1 |
alignment of d = 4 | alignment of d = 1 |
union uu {
short a;
struct {
char x;
char y;
char z;
} b;
};
union uu nonpacked[2];
Since the largest alignment
requirement among the union members is that of short a,
namely, 2 bytes, one byte of padding is added at the end of each union
in the array to enforce this requirement: ┌───── nonpacked[0] ─────────── nonpacked[1] ───┐ │ │ │ │ a │ │ a │ │ │ x │ y │ z │ │ x │ y │ z │ │ |─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘ 0 1 2 3 4 5 6 7 8The next example uses #pragma pack(1) to set the alignment of unions of type uu to 1 byte:
#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