https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69560
Peter Cordes <peter at cordes dot ca> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |peter at cordes dot ca --- Comment #23 from Peter Cordes <peter at cordes dot ca> --- Just to recap the current situation (gcc/g++ 8.0.1 20180425): I ported David Marillat's testcase to work as C or C++ https://godbolt.org/g/QdG2V6. (And changed it to set global variables instead of calling printf, so you can see the results from looking at the asm output instead of running it). C++11 alignof() now agrees with C11 alignof() (which didn't change) that alignof(int64_t) is 4 when targeting the i386 System V ABI. Previously G++'s alignof() reported 8, while gcc's C11 alignof (stdalign.h) reported 4. That was the only change: struct-member alignof results are unchanged, and already matched between C11 and C++11. 4 is the minimum alignment that *any* int64_t, or pointer to int64_t, is assumed to have when generating code for i386 SysV. gcc / g++ are allowed to generate code that breaks if passed a pointer to int64_t that wasn't 4-byte aligned. (Auto-vectorization is one case where that can happen on x86: https://stackoverflow.com/q/47510783/224132). They're *not* allowed to assume that it's 8-byte aligned unless they can see the definition and know that a particular int64_t object is over-aligned, e.g. to its natural alignment of 8, like gcc chooses to do whenever possible (i.e. outside structs). So in both C++ and C (and in g++/gcc after this patch), alignof(int64_t) is the minimum that any allocator must give an int64_t for correctness (in this funky 32-bit ABI), not the recommended alignment that gcc and g++ both already used whenever ABI struct-packing rules didn't constrain them. It's also the guaranteed minimum that code can *assume*. e.g. a manually-vectorized library function might check alignof(T) == sizeof(T) before assuming that using 16-byte aligned loads/stores can line up with element boundaries. (An array inside a struct { int foo; int64_t arr[10]; } would violate this for i386 SysV). Anyway, I think use-cases like these are why the standard is worded the way it is, and why it makes sense for alignof() to report the guaranteed/required minimum. The recommended or actual alignment is useful, too, though, for other cases, so it's nice that GNU __alignof() is also available to report that. ---- Semi-related: gcc depends on 8-byte alignment for C11 _Atomic int64_t but still fails to provide it inside structs on the i386 SysV ABI (Bug 65146), using the same alignment rules as regular int64_t. C++11 std::atomic<int64_t> is fine, getting the required natural alignment even on i386 SysV so SSE2 movq is atomic and lock add is efficient. This change to what alignof() reports in C++ had no effect on C at all, or on any alignment choices made by the compiler in either C or C++. I only mention it as another interesting case where i386 SysV's under-alignment of 64-bit types requiring special care, but that one will require an ABI change of some sort to fix.