I'm moving some C++17 code to be used in a project that is built with Qt, on Windows, using MinGW 7.3.0, and noticed something weird happening in the 32bit builds:
#include#include int main() { std::cout << __STDCPP_DEFAULT_NEW_ALIGNMENT__ << std::endl; std::cout << __BIGGEST_ALIGNMENT__ << std::endl; std::cout << sizeof(std::max_align_t) << std::endl; std::cout << alignof(std::max_align_t) << std::endl; std::cout << "----------------------------------------" << std::endl; for (int i = 0; i < 8; ++i) { const uintptr_t ptr = uintptr_t(new char); static const uintptr_t first = ptr; std::cout << (ptr - first) << " " // << (ptr % 16) << " " // << (ptr % 8) << std::endl; } return 0; }
Outputs:
16 16 24 8 ---------------------------------------- 0 8 0 48 8 0 64 8 0 80 8 0 96 8 0 112 8 0 128 8 0 144 8 0
The same thing happens if I use bigger types / structs instead of char
, and also if I call ::operator new(size_t)
directly with various sizes, instead of the new operator.
As you can see, STDCPP_DEFAULT_NEW_ALIGNMENT
is 16, but I get pointers that are only 8-aligned.
My understanding was that in C++17 operator new(size_t)
would always return pointers with alignment of at least STDCPP_DEFAULT_NEW_ALIGNMENT
, and the two parameter operator new(size_t, align_val_t)
is only required for alignments exceeding STDCPP_DEFAULT_NEW_ALIGNMENT
. Here, it seems, operator new(size_t)
only respects the lower alignof(std::max_align_t)
.
Is this expected behavior? What am I getting wrong here? This seems to contradict my reading of: https://en.cppreference.com/w/cpp/memory/new/operator_new