Data structure members are stored sequentially in memory so that, in the structure below, the member data1 will always precede data2; and data2 will always precede data3: struct MyData { short data1; short data2; short data3; }; If the type short is stored in two bytes of memory then each member of the data structure depicted above would be 2-byte aligned. data1 would be at offset 0, data2 at offset 2, and data3 at offset 4. The size of this structure would be 6 bytes. The type of each member of the structure usually has a default alignment, meaning that it will, unless otherwise requested by the programmer, be aligned on a pre-determined boundary. The following typical alignments are valid for compilers from
Microsoft (
Visual C++),
Borland/
CodeGear (
C++Builder),
Digital Mars (DMC), and
GNU (
GCC) when compiling for 32-bit x86: • A char (one byte) will be 1-byte aligned. • A short (two bytes) will be 2-byte aligned. • An int (four bytes) will be 4-byte aligned. • A long (four bytes) will be 4-byte aligned. • A float (four bytes) will be 4-byte aligned. • A double (eight bytes) will be 8-byte aligned on Windows and 4-byte aligned on Linux (8-byte with the '''' compile time option). • A long long (eight bytes) will be 8-byte aligned on Windows and 4-byte aligned on Linux (8-byte with the '''' compile time option). • A long double (ten bytes with C++Builder and DMC, eight bytes with Visual C++, twelve bytes with GCC) will be 8-byte aligned with C++Builder, 2-byte aligned with DMC, 8-byte aligned with Visual C++, and 4-byte aligned with GCC. • Any
pointer (four bytes) will be 4-byte aligned. (e.g.: char*, int*) The only notable differences in alignment for an
LP64 64-bit system when compared to a 32-bit system are: • A long (eight bytes) will be 8-byte aligned. • A double (eight bytes) will be 8-byte aligned. • A long long (eight bytes) will be 8-byte aligned. • A long double (eight bytes with Visual C++, sixteen bytes with GCC) will be 8-byte aligned with Visual C++ and 16-byte aligned with GCC. • Any
pointer (eight bytes) will be 8-byte aligned. Some data types are dependent on the implementation. Here is a structure with members of various types, totaling
8 bytes before compilation: struct MixedData { char c1; short s; int i; char c2; }; After compilation the data structure will be supplemented with padding bytes to ensure a proper alignment for each of its members: // After compilation in 32-bit x86 machine struct MixedData { char c1; // 1 byte // 1 byte for the following 'short' to be aligned on a 2-byte boundary // assuming that the address where structure begins is an even number char padding1[1]; short s; // 2 bytes int i; // 4 bytes - largest structure member char c2; // 1 byte char padding2[3]; // 3 bytes to make total size of the structure 12 bytes }; The compiled size of the structure is now 12 bytes. The last member is padded with the number of bytes required so that the total size of the structure should be a multiple of the largest alignment of any structure member ( in this case, which = 4 on linux-32bit/gcc). In this case 3 bytes are added to the last member to pad the structure to the size of 12 bytes (). struct FinalPad { float x; char n[1]; }; In this example the total size of the structure , not 5 (so that the size is a multiple of 4 ()). struct FinalPadShort { short s; char n[3]; }; In this example the total size of the structure , not 5 (not 8 either) (so that the size is a multiple of 2 ( on linux-32bit/gcc)). It is possible to change the alignment of structures to reduce the memory they require (or to conform to an existing format) by reordering structure members or changing the compiler's alignment (or “packing”) of structure members. // after reordering struct MixedData { char c1; char c2; short s; int i; }; The compiled size of the structure now matches the pre-compiled size of
8 bytes. Note that has been replaced (and thus eliminated) by and is no longer necessary as the structure is already aligned to the size of a long word. The alternative method of enforcing the structure to be aligned to a one byte boundary will cause the pre-processor to discard the pre-determined alignment of the structure members and thus no padding bytes would be inserted. While there is no standard way of defining the alignment of structure members (while C and C++ allow using the specifier for this purpose it can be used only for specifying a stricter alignment), some compilers use directives to specify packing inside source files. Here is an example: • pragma pack(push) // push current alignment to stack • pragma pack(1) // set alignment to 1-byte boundary struct MyPackedData { char c1; long l; char c2; }; • pragma pack(pop) // restore original alignment from stack This structure would have a compiled size of
6 bytes on a 32-bit system. The above directives are available in compilers from
Microsoft,
Borland,
GNU, and many others. Another example: struct MyPackedData { char c1; long l; char c2; } __attribute__((packed));
Default packing and On some Microsoft compilers, particularly for RISC processors, there is an unexpected relationship between project default packing (the /Zp directive) and the directive. The directive can only be used to
reduce the packing size of a structure from the project default packing. This leads to interoperability problems with library headers which use, for example, , if the project packing is smaller than this. For this reason, setting the project packing to any value other than the default of 8 bytes would break the directives used in library headers and result in binary incompatibilities between structures. This limitation is not present when compiling for x86. ==Allocating memory aligned to cache lines==