This is about memory alignment. In code below, I expected that the offset of b inside the structure to be 8 (32-bit machine). See here. There by, making b
alway
According to the System V ABI for i386, page 28, double
only gets 4 bytes alignment, but compilers are recommended to provide an option for 8 bytes as well. It appears this is what is implemented by GCC on Linux, the option being called -malign-double
.
Another alternative is to use -m64
to get x86-64 object code, which is already the default on some systems including Mac OS X.
There is no guarantee about alignment, at all, in ANSI C.
The alignment happens with automatic variables more than with anything declared on the heap. If you're on a POSIX OS, use memalign(3) to receive memory that you're sure is aligned. Malloc may return memory at any offset. You can use compiler directives like __attribute__ ((__packed__))
to put in your own alignments.
I expected that the offset of b inside the structure to be 8 (32-bit machine). See here
Your references explain why it could be advantageous to 8-align doubles. This doesn't amount to a guarantee that doubles will always be 8-aligned. If your sources say that they're always 8-aligned, and you observe an implementation in which they aren't, then your sources are wrong.
From the GCC man page:
Aligning "double" variables on a two word boundary will produce code that runs somewhat faster on a Pentium at the expense of more memory.
So GCC's stated reason for 4-alignment is to save memory. You can use -malign-double
and -mno-align-double
to control that, although of course you risk creating binary incompatibilities if you share structs between code compiled with conflicting options. For particular objects/struct members you can use GCC's own __attribute__((aligned)), _Alignas
(in C11) or alignas
(in C++11), all of which can take an integer constant to specify the required alignment.