This is exert from a book about data alignment of primitive types in memory.
Microsoft Windows imposes a stronger alignment requirement—any primitive object of K bytes, for
K = 2, 4, or 8, must have an address that is a multiple of K. In particular, it requires that the address
of a double or a long long be a multiple of 8. This requirement enhances the memory performance at
the expense of some wasted space. The Linux convention, where 8-byte values are aligned on 4-byte
boundaries was probably good for the i386, back when memory was scarce and memory interfaces were
only 4 bytes wide. With modern processors, Microsoft’s alignment is a better design decision. Data type
long double, for which gcc generates IA32 code allocating 12 bytes (even though the actual data type
requires only 10 bytes) has a 4-byte alignment requirement with both Windows and Linux.
Questions are:
- What imposes data alignment, OS or compiler?
- Can I change it or it is fixed?
Generally speaking, it’s the compiler that imposes the alignment. Whenever you declare a primitive type (eg.
double), the compiler will automatically align it to 8 bytes on the stack.Furthermore, memory allocations are also generally aligned to the largest primitive type so that you can safely do this:
without having to worry about alignment.
Therefore, generally speaking, if you’re programming with good habits, you won’t have to worry about alignment. One way to get something misaligned is to do something like this:
There are some exceptions to this: When you start getting into SSE and vectorization, things get a bit messy because
mallocno longer guarantees 16-byte alignment.To override the alignment of something, MSVC has the
declspec(align)modifier which will allow this. It’s used to increase the alignment of something.Though I’m not sure if it lets you decrease the alignment of a primitive type.It says explicitly that you cannot decrease alignment with this modifier.EDIT :
I found the documentation stating the alignment of
malloc()on GCC:Source: http://www.gnu.org/s/hello/manual/libc/Aligned-Memory-Blocks.html
So yes, GCC now aligns to at least 8 bytes.