Visual C++ not respecting alignment for stack variables

Viewed 107

The following sometimes fails after compiling for x86 with Visual Studio 16.8.1:

#include <cassert>
#include <cstdint>

struct X { uint64_t value; };

int main() {
    X x;
    assert(reinterpret_cast<uintptr_t>(&x) % alignof(X) == 0);
}

Interestingly, the assert doesn't trigger if X has an explicit alignment specifier: struct alignas(uint64_t) X.

Am I correct to assume this is a compiler bug and not some quirk of the C++ standard?

1 Answers

It's a bug.

On x86, some operations may incur a performance penalty unless the operand is naturally aligned. Apparently Visual C++ has a nonconformant alignof operator which returns the natural alignment instead of the required alignment for a type. When building with MSVC for 32-bit, the natural alignment of uint64_t / double is 8, while its required alignment is 4. So in the code above the address of x must be a multiple of 4, but not necessarily a multiple of alignof(X).

This baffling behavior is underlined by uint64_t x; not having the same meaning as alignas(uint64_t) uint64_t x;. Only the latter has the expected alignment.

See also: GCC fixing a similar bug and associated libc++ updates.

Related