Effects of Structure Packing for 16-Bit Targets

ID: Q67735


The information in this article applies to:


SUMMARY

Microsoft compilers provides two methods to specify structure packing: a command-line option (/Zp) and a pragma (pack). When the compiler packs a structure, it aligns the elements of the structure on a 1-, 2-, or 4-byte boundary in memory. An application can use packing for indexing purposes or to decrease processor access time. Unless an application specifies a different value, the default structure packing value is two.

The field size and packing value determine the amount of padding required before a field appears in the structure. The padding can change the offset of a particular member of the structure.

The compiler calculates each offset of a structure member relative to zero (0). The compiler compares the size of each member to the packing value (which is also known as the alignment value). The compiler aligns the element on the boundary of the smaller of the field size and the packing value.

Finally, the compiler can pad the entire structure to properly align arrays of structures. The compiler usually pads all structures to a multiple of the packing size. However, if the specified packing size is four, but the structure does not contain any element larger than 2 bytes, the structure is padded to a multiple of two.

The structures are not packed to a multiple of the packing size whenever the structure does not contain any elements (or elements of arrays) that are equal to or greater than the packing size. For example, structs of just chars or arrays of chars are never padded.


MORE INFORMATION

The sample code below shows a structure that is packed one a one-byte boundary [/Zp1 or #pragma pack(1)]. The structure first appears as it would in source code, followed by an indication of its storage in memory and the assembly language code generated for the structure.

Structure #1


struct
{
   char a;
   int b;
   char c;
} dummy; 

Packed Structure #1


struct
{
   char a;
   int b;
   char c;
} 

Assembly Code Generated in Small Model


_BSS SEGMENT WORD PUBLIC 'BSS'
_BSS ENDS
...
_BSS SEGMENT
COMM NEAR _dummy:BYTE:4
_BSS ENDS 
Note that the assembly language listing shows that the structure is 4-bytes long and no padding at the end is required.

The sample code below shows a structure that is packed on a 2-byte boundary [/Zp2 or #pragma pack(2)].

Structure #2


struct
{
   char a;
   int b;
   char c;
} dummy; 

Packed Structure #2


struct
{
   char a;
   (Filler character here)
   int b;
   char c;
   (Filler character here)
} 

Assembly Code Generated in Small Model


_BSS SEGMENT WORD PUBLIC 'BSS'
_BSS ENDS
...
_BSS SEGMENT
COMM NEAR _dummy:BYTE:6
_BSS ENDS 
In this case, note that the compiler pads the structure to start the b member on a 2-byte boundary and pads the entire structure so its length is a multiple of two. Therefore the length is 6 bytes.

The sample code example below shows a structure that is packed on a 4-byte boundary [/Zp4 or #pragma pack(4)].

Structure #3


struct
{
   char a;
   int  b;
   long c;
   char d;
} dummy; 

Packed Structure #3


struct
{
   char a;
   (1 filler character here)
   int  b;
   long c;
   char d;
   (3 filler characters here)
} 

Assembly Code Generated in Small Model


_BSS SEGMENT WORD PUBLIC 'BSS'
_BSS ENDS
...
_BSS SEGMENT
COMM NEAR _dummy:BYTE:12
_BSS ENDS 
This case is somewhat more complex. The first padding relates to the placement of the b member. Because the field size for an integer is two and the alignment value is four, the compiler aligns the integer on a 2-byte boundary (the field size is smaller). The c member requires alignment on a 4-byte boundary; no padding is required. Finally, the compiler pads the length of the entire structure to a multiple of four.

Additional query words: kbinf 1.00 1.50 6.00 6.00a 6.00ax 7.00 8.00 8.00c


Keywords          : kb16bitonly 
Version           : 
Platform          : 
Issue type        : 

Last Reviewed: July 21, 1999