Effects of Structure Packing for 16-Bit Targets

Last reviewed: July 17, 1997
Article ID: Q67735
6.00 6.00a 6.00ax 7.00 | 6.00 6.00a | 1.00 1.50
MS-DOS                 | OS/2       | WINDOWS
kbtool

The information in this article applies to:

  • The Microsoft C/C++ Compiler (CL.EXE), included with:

        - Microsoft C for MS-DOS, versions 6.0, 6.0a, and 6.0ax
        - Microsoft C for OS/2, versions 6.0 and 6.0a
        - Microsoft C/C++ for MS-DOS, versions 7.0
        - Microsoft Visual C++ for Windows, versions 1.0 and 1.5
    

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 reference words: kbinf 1.00 1.50 6.00 6.00a 6.00ax 7.00 8.00
8.00c
KBCategory: kbtool
KBSubcategory: CLIss
Keywords : kb16bitonly


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: July 17, 1997
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.