#pragma Pack Preprocessor Command Example

Updated Apr 17, 2018

Reported In

Software

  • LabWindows/CVI Base
  • LabWindows/CVI Full

Issue Details

Are there examples of how the #pragma pack preprocessor command works?

Solution

The #pragma pack command is a preprocessor statement that can be used to specify the maximum alignment factor in LabWindows/CVI™. This behavior was added in LabWindows/CVI™ 4.0. 

Below is code creating two structs to compare normal behavior with #pragma pack.
struct {
   char a;
   short b;
   char c;
} s1;		
	
struct {
   short x;
   char y;
   char z;
} s2;		  
	
p = sizeof(s1);
q = sizeof(s2);


In LabWindows/CVI™ 3.1 the values of both p and q will be 4.

s1: 1 byte (char) + 2 bytes (short) + 1 byte (char) = 4 bytes (structure), so p = 4
s2: 2 bytes (short) + 1 byte (char) + 1 byte (char) = 4 bytes (structure), so q = 4



In LabWindows/CVI™ 4.0 and later you can use the #pragma pack preprocessor statement to define the maximum alignment value for storing members of a structure in memory. When you use #pragma pack(n) -- where n can be 1, 2, 4, 8, or 16 -- each structure member is stored with an alignment equal to the value of n or the byte size of the member type, whichever is smaller. If you use #pragma pack without an argument, then structure members are packed according to the compiler's default value.

Here are the results in LabWindows/CVI™ 4.0.1:
#pragma pack (1)              p = 4, q = 4; 
#pragma pack (2)              p = 6, q = 4;
#pragma pack (4)              p = 6, q = 4;

Why are p and q the same in the 2nd and 3rd case?
The only difference between structures s1 and s2 is the order in which the variables are declared. Here are the cases:

Using #pragma pack (1)
In this mode, LabWindows/CVI™ will pack the structure members on every 1 byte boundary, meaning that there will be no padding between members in the structure.


Using #pragma pack (2)
In this mode, LabWindows/CVI™ will pack on every 2 byte boundary or on the structure member's size, whichever is smaller. This means that char data types will pack on a 1 byte boundary and short data types will pack on a 2 byte boundary. Structure s1 will pack in this order:
  • char a packs on a 1 byte boundary, so s1.a is stored at byte 0, occupying 1 byte of memory
  • short b packs on a 2 byte boundary, so s1.b is stored at byte 2 (which means there will be a 1 byte pad at byte 1), occupying 2 bytes of memory (byte 2 and byte 3)
  • char c packs on a 1 byte boundary, so s1.c is stored at byte 4, occupying 1 byte of memory
Structure s2 will pack immediately after structure s1 and it will pack in this order:
  • short x packs on a 2 byte boundary, so s2.x is stored at byte 6 (which means there will be a 1 byte pad at byte 5, added to the end of structure s1), occupying 2 bytes of memory (byte 6 and byte 7)
  • char y packs on a 1 byte boundary, so s2.y is stored at byte 8, occupying 1 byte of memory
  • char z packs on a 1 byte boundary, so s2.z is stored at byte 9, occupying 1 byte of memory
Thus, structure s1 will return a size of 6 and structure s2 will return a size of 4.


Using #pragma pack (4)
In this mode, LabWindows/CVI™ will pack on every 4 byte boundary or on the structure member's size, whichever is smaller. This means that char data types will pack on a 1 byte boundary and short data types will pack on a 2 byte boundary, the same as using #pragma pack (2).


See the attached file (pragma.zip) for an image (pragma.gif), which displays the way these two structures are stored in memory.
 

Attachments