The fundamental alignment is represented by alignof(std::max_align_t)
. It means that any supported alignment is less than this value.
std::max_align_t
was introduced by C++11. It means that any type of alignment requirement can be met as long as alignof(std::max_align_t)
is followed.
The introduction of __STDCPP_DEFAULT_NEW_ALIGNMENT__
in C++17 is accompanied by the introduction of operator new(std::size_t count, std::align_val_tal)
. In order to distinguish what alignment requirements will use the align version of operator new, and what alignment requirements will use the non-align version of new, __STDCPP_DEFAULT_NEW_ALIGNMENT__
gives a clear definition. Any alignment requirements greater than this value will use the align version of new. In addition, all non-align versions of new are used.
So since C++17 introduced key points
When overloading operator new, if the non-aligned version of operator new overloaded version is called, it means that the alignment requirement of this allocation is less than or equal to __STDCPP_DEFAULT_NEW_ALIGNMENT__
, but you still don’t know whether the allocation comes from new char
or new short
or new long
. According to the classic solution, set the alignment to the maximum alignment. So at least this value is greater than or equal to alignof(std::max_align_t)
. Take MSVC as an example, alignof(std::max_align_t)
is 8, then this value must be greater than or equal to 8. However, if the alignment requirement is 16, the non-aligned version of operator new will also be called, and the 8-alignment will not meet the requirement. So this value must be promoted to __STDCPP_DEFAULT_NEW_ALIGNMENT__
in order to satisfy any alignment requirements for calling the non-align version new.
Why doesn't the compiler set __STDCPP_DEFAULT_NEW_ALIGNMENT__
to alignof(std::max_align_t)
? This is determined by the hardware requirements and the implementation of the compiler. Each compiler will set up according to their actual needs, we just need to follow the standards. We can also study why MSVC is 16, but remember that other platforms will have another value.
So before C++17 and after C++11, how can we align without __STDCPP_DEFAULT_NEW_ALIGNMENT__
? Note: Before C++17, there was no __STDCPP_DEFAULT_NEW_ALIGNMENT__
nor operator new(std::size_t count, std::align_val_t al)
. At this time, all operator new will call the non-align version. Then this version of the operator implementation must be the largest case, because the actual alignment requirements of the actual allocation type cannot be known. We just need to follow alignof(std::max_align_of)
. A paradoxical problem is that I just used __STDCPP_DEFAULT_NEW_ALIGNMENT__
with C++17 on my local Windows. I already know that the hardware and compiler requirements of my platform are 16. Then when I switch to C++11 compilation, shall I still use 16? The answer is no, because C++11 does not have any standard that tells us something like __STDCPP_DEFAULT_NEW_ALIGNMENT__
, so its compiler will not assume that its operator new will be aligned according to 16. We only need to follow the alignment requirement alignof(std::max_align_t)
established by the current standard.
What about C++98 era that before C++11, how should overloaded operator new be aligned? Because there is no standard to regulate a unified place for obtaining alignment information, then application programmers can only restrict themselves according to the actual situation of their own platforms.