Double alignment

c, c++, memory-alignment, structure

Solution

An extended comment:

According to GCC documentation about `-malign-double`:

Aligning `double` variables on a two-word boundary produces code that runs somewhat faster on a Pentium at the expense of more memory.

On x86-64, `-malign-double` is enabled by default.

Warning: if you use the `-malign-double` switch, structures containing the above types are aligned differently than the published application binary interface specifications for the 386 and are not binary compatible with structures in code compiled without that switch.

A word here means i386 word which is 32 bits.

Windows uses 64-bit alignment of `double` values even in 32-bit mode, while SysV i386 ABI conformant Unices use 32-bit alignment. The 32-bit Windows API, Win32, comes from Windows NT 3.1, which, unlike current generation Windows versions, targeted Intel i386, Alpha, MIPS and even the obscure Intel i860. As native RISC systems like Alpha and MIPS require `double` values to be 64-bit aligned (otherwise hardware fault occurs), portability might have been the rationale behind the 64-bit alignment in the Win32 i386 ABI.

64-bit x86 systems, know also as AMD64 or x86-64, or x64, require `double` values to be 64-bit aligned otherwise a misalignment fault occurs and the hardware does an expensive "fix-up" which considreably slows down memory access. That's why `double` values are 64-bit aligned in all modern x86-64 ABIs (SysV and Win32).

Problem

Following the discussion from this post, I have understood that the main reason for the alignment of structure members is performance (and some architectures restrictions). If we will investigate Microsoft (Visual C++), Borland/CodeGear (C++-Builder), Digital Mars (DMC) and GNU (GCC) when compiling for 32-bit x86: The alignment for `int` is 4 bytes and if `int` is not aligned, it can happen that 2 rows of memory banks will be read. My question is why not to make `double` to be 4 bytes aligned also? 4 bytes aligned `double` also will cause 2 rows of memory banks reading.... For example in the following example, since `double` is 8-aligned, the actual size of structure will be `sizeof(char) + (alignment for double padding) + sizeof(int) = 20 bytes`. ``` typedef struct structc_tag{ char c; double d; int s; } structc_t; ``` Thank you

Original source

Related problems