Applications should generally align structure members at addresses that are “natural” for the data type and the processor involved. For example, a 4-byte data member should have an address that is a multiple of four.
This principle is especially important when you write code for porting to multiple processors. A misaligned 4-byte data member, which is on an address that is not a multiple of four, causes a performance penalty with an 80386 processor and a hardware exception with a MIPS® RISC processor. In the latter case, although the system handles the exception, the performance penalty is significantly greater.
The following guidelines ensure proper alignment for processors targeted by Win32:
|char||Align on byte boundaries|
|short (16-bit)||Align on even byte boundaries|
|int and long (32-bit)||Align on 32-bit boundaries|
|float||Align on 32-bit boundaries|
|double||Align on 64-bit boundaries|
|structures||Largest alignment requirement of any member|
|unions||Alignment requirement of the first member|
The compiler automatically aligns data in accordance with these requirements, inserting padding in structures up to the limit (default pack size) specified by the /Zp option or #pragma pack. For example, /Zp2 permits up to 1 byte of padding, /Zp4 permits up to 3 bytes of padding, and so on. The default pack size for Windows 3.x is 2, whereas the default for Win32 is 8. As a consequence:
If you have specified a packing limit with /Zp or #pragma pack, you may not get the proper alignment (the default value) for Win32.
The different default setting for Win32 can impact your source code by changing the offsets of some structure members. Examine your code closely to see whether you have hard-coded these offsets, or whether your code makes assumptions based on a certain default pack size.