分类: 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. |