#pragma pack

Category

Object code control

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

Read syntax diagramSkip visual syntax diagram
>>-#--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)
Begin C++ only
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.
End C++ only
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 C++ only #pragma pack(pop)
End C++ only
or C only #pragma pack(4) C only.
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.

The #pragma pack directive applies only to complete declarations of structures or unions; this excludes forward declarations, in which member lists are not specified. For example, in the following code fragment, the alignment for struct S is 4, since this is the rule in effect when the member list is declared:
#pragma pack(1)
struct S;
#pragma pack(4)
struct S { int i, j, k; };
A nested structure has the alignment that precedes its declaration, not the alignment of the structure in which it is contained, as shown in the following example:
#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

The following example shows how the #pragma pack directive can be used to set the alignment of a structure definition:
//  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
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):
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
The following example defines a union uu containing a structure as one of its members, and declares an array of 2 unions of type uu:
          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     8
The 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];
Now, each union in the array packed has a length of only 3 bytes, as opposed to the 4 bytes of the previous case:
         ┌─── packed[0] ───┬─── packed[1] ───┐
         │                 │                 │
         │     a     │     │     a     │     │
         │  x  │  y  │  z  │  x  │  y  │  z  │
         ⋘─────┴─────┴─────┴─────┴─────┴─────┘
         0     1     2     3     4     5     6