#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
Default #pragma pack syntax

>>-#--pragma--pack--(--+--------+--)---------------------------><
                       +-nopack-+      
                       +-number-+      
                       '-pop----'      

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

nopack
Disables packing. A warning message is issued and the pragma is ignored.
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
Aligns structure members on 8-byte boundaries, or on their natural alignment boundary, whichever is less.
16
Aligns structure members on 16-byte boundaries, or on their natural alignment boundary, whichever is less.
pop
Removes the previous value added with #pragma pack. Specifying #pragma pack() with no parameters is equivalent to pop.

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 aligns all bit fields in a structure/union on 1-bit boundaries. Example:
#pragma pack(2)
struct A{
int a:31;
int b:2;
}x;

int main(){
printf("size of S = %d\n", sizeof(s));
}

When compiled and run, the output is:
size of S = 6

But if you remove the #pragma pack directive, you get this output:
size of S = 8
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(pop)       //   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

Related information