#pragma pack

Description

The #pragma pack directive modifies the current alignment rule for members of structures following the directive.

Syntax

Read syntax diagramSkip visual syntax diagram>>-#--pragma--pack--(--+--------+--)---------------------------><
                       +-nopack-+
                       +-1------+
                       +-2------+
                       +-4------+
                       +-8------+
                       +-16-----+
                       '-pop----'

where:

1 | 2 | 4 | 8 | 16 Members of structures are aligned on the specified byte-alignment, or on their natural alignment boundary, whichever is less, and the specified value is pushed on the stack.
nopack No packing is applied, and "nopack" is pushed onto the pack stack
pop The top element on the pragma pack stack is popped.

Notes

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 according to the alignment rule.

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 integer (int), a #pragma pack(2) directive would cause that member to be packed in the structure on a 2-byte boundary, while a #pragma pack(4) directive would have no effect.

The #pragma pack directive is stack based. All pack values are pushed onto a stack as the source code is parsed. The value at the top of the current pragma pack stack is the value used to pack members of all subsequent structures within the scope of the current alignment rule.

A #pragma pack stack is associated with the current element in the alignment rule stack. Alignment rules are specified with the -qalign compiler option or with the #pragma options align directive. If a new alignment rule is specified, a new #pragma pack stack is created. If the current alignment rule is popped off the alignment rule stack, the current #pragma pack stack is emptied and the previous #pragma pack stack is restored. Stack operations (pushing and popping pack settings) affect only the current #pragma pack stack.

The #pragma pack directive does not affect the alignment of the bits in a bit field.

Examples

  1. In the code shown below, the structure s_t2 will have its members packed to 1-byte, but structure s_t1 will not be affected. This is because the declaration for s_t1 began before the pragma directive. However, s_t2 is affected because its declaration began after the pragma directive.
    struct s_t1 {
        char a;	
        int b;
        #pragma pack(1)
        struct s_t2 {	
                char x;
                int y;
        } S2;
        char c;
        int d;
    } S1;
  2. In the code segment below:
    1. The members of s_t1 would be aligned with the twobyte alignment rule, s_t2 members would be packed on 1-byte, s_t3 members packed on 2-bytes, and s_t4 packed on 4-bytes.
    2. The #pragma options align=reset directive pops the current alignment rule (which in the above case was the twobyte alignment rule). All #pragma pack directives issued while the #pragma options align=twobyte directive was in effect are also popped.
    3. The #pragma pack(4) directive encountered is restored, as well as the alignment rule that was in effect before the #pragma options align=twobyte directive was popped.
    #pragma pack(4)
    #pragma options align=twobyte
    struct s_t1 {
    	char a;
    	int b;
    }S1;
    
    #pragma pack(1)
    struct s_t2 {
    	char a;
    	short b;
    } S2;
    
    #pragma pack(2)
    struct s_t3 {
    	char a;
    	double b;
    } S3;
    
    #pragma options align=reset
    struct s_t4 {
    	char a;
    	int b;
    } S4;
    
  3. This example shows how a #pragma pack directive can affect the size and mapping of a structure:
    struct s_t {
    	char a;
    	int b;
    	short c;
    	int d;
    }S;
    
    Default mapping: With #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

Related information