分类: C/C++
2011-01-10 09:39:03
#pragma pack [ ([[max_member_alignment], [min_structure_alignment][, byte-swap]]) ]
| The pack directive specifies that all subsequent structures are to use the alignments given by max_member_alignment and min_structure_alignment where: |
| max_member_alignment |
| Specifies the maximum alignment of any member in a structure. If the natural alignment of a member is less than or equal to max_member_alignment, the natural alignment is used. If the natural alignment of a member is greater than max_member_alignment, max_member_alignment will be used. |
| Thus, if max_member_alignment is 8, a 4-byte integer will be aligned on a 4-byte boundary. While if max_member_alignment is 2, a 4-byte integer will be aligned on a 2-byte boundary. |
| min_structure_alignment |
| Specifies the minimum alignment of the entire structure itself, even if all members have an alignment that is less than min_structure_alignment. |
| byte-swap |
| If 0 or absent, bytes are taken as is. If 1, bytes are swapped when the data is transferred between byte-swapped members and registers or non-byte-swapped memory. This enables access to little-endian data on a big-endian machine and vice-versa. |
| It is not possible to take the address of a byte-swapped member. |
| If neither max_member_alignment nor min_structure_alignment are given, they are both set to 1. If either max_member_alignment or min_structure_alignment is zero, the corresponding default alignment is used. If max_member_alignment is non-zero and min_structure_alignment is not given it will default to 1. |
| The form #pragma pack is equivalent to #pragma pack(1,1,0). The form #pragma pack( ) is equivalent to #pragma pack(0,0,0). |
| The align pragma, provided for portability, is an exact synonym for pack. |
| An alternative method of specifying structure padding is by using . |
| Default values for max_member_alignment and min_structure_alignment can be set by using the -Xmember-max-align and the -Xstruct-min-align options. The order of precedence is values -X options lowest, then the packed pragma, and __packed__ or packed keyword highest. |
| Note that if a structure is not packed, the compiler will insert extra padding to assure that no alignment exception occurs when accessing multi-byte members, if required by the selected processor. See . |
| When a structure is packed, if the processor requires that multi-byte values be aligned (-Xalign-min > 1), the following restrictions apply: |
| • | Access to multi-byte members will require multiple instructions. (This is so even if a member is aligned as would be required within the structure because the structure may itself be placed in memory at a location such that the member would be unaligned, and this cannot be determined at compile time.) |
| • | volatile members cannot be accessed atomically. The compiler will warn and generate multiple instructions to access the volatile member. Also, "compound" assignment operators to volatile members, such as +=, |=, etc., are not supported. For example, assuming i is a volatile member of packed structure struct1, then the statement: |
struct1.i += 3;
| must be recoded as: |
struct1.i = struct1.i + 3;
| In addition, for packed structures, an enum member will use the smallest type sufficient to represent the range, see . |
| Later examples depend on earlier examples in some cases. |
|
#pragma pack (2,2) |
|
|
struct s0 { |
|
|
char a; |
1 byte at offset 0, 1 byte padding |
|
short b; |
2 bytes at offset 2 |
|
char c; |
1 byte at offset 4 |
|
char d; |
1 byte at offset 5 |
|
int e; |
4 bytes at offset 6 |
|
char f; |
1 byte at offset 10 |
|
}; |
total size 11, alignment 2 |
| If two such structures are in a section beginning at offset 0xF000, the layout would be: |
![]() |
|
#pragma pack (1) |
Same as #pragma pack(1,1), no padding. | ||
|
struct S1 { |
|||
|
char c1 |
1 byte at offset 0 | ||
|
long i1; |
4 bytes at offset 1 | ||
|
char d1; |
1 byte at offset 5 | ||
|
}; |
total size 6, alignment 1 | ||
|
|
|||
|
#pragma pack (8) |
Use "natural" packing for largest member. | ||
|
struct S2 { |
|||
|
char c2 |
1 byte at offset 0, 3 bytes padding | ||
|
long i2; |
4 bytes at offset 4 | ||
|
char d2; |
1 byte at offset 8, 3 bytes padding | ||
|
}; |
total size 12, alignment 4 | ||
|
|
|||
|
#pragma pack (2,2) |
Typical packing on machines which cannot | ||
|
struct S3 { |
| ||
|
char c3; |
1 byte at offset 0, 1 byte padding | ||
|
long i3; |
4 bytes at offset 2 | ||
|
char d3; |
1 byte at offset 6, byte padding | ||
|
}; |
total size 8, alignment 2 | ||
|
|
|||
|
struct S4 { |
Using pragma from prior example. | ||
|
char c4; |
1 byte at offset 0, 1 byte padding | ||
|
}; |
total size 2, alignment 2 since | ||
|
|
| ||
|
|
|||
|
#pragma pack (8) |
"Natural" packing since S3 is 8 bytes long. | ||
|
struct S { |
|||
|
char e1; |
1 byte at offset 0 | ||
|
struct S1 s1; |
6 bytes at offset 1, 1 byte padding | ||
|
struct S2 s2; |
12 bytes at offset 8 | ||
|
char e2; |
1 byte at offset 20, 1 byte padding | ||
|
struct S3 s3; |
8 bytes, at offset 22, 2 bytes padding alignment 2 | ||
|
}; |
total size 32, alignment 4 | ||
|
|
|||
|
#pragma pack (0) |
Set to default packing. |