Does the C++17 standard requires
#include <cstddef>
static_assert(__STDCPP_DEFAULT_NEW_ALIGNMENT__ >= alignof(std::max_align_t));
to be true?
In other words, is it safe to assume the address returned by
auto ptr = new std::byte[size];
is suitably aligned for any scalar type?
Something similar has been asked in a more wide question here, but there is no specific answer to this point. Also, there is something interesting in this answer, but I am not sure it answer my question. I've already tried almost all platforms supported by Godbolt with no surprises: https://godbolt.org/z/ErPjYaE55.
Prior to C++17 and P0035R4, we had (in [basic.align]p2):
A fundamental alignment is represented by an alignment less than or equal to the greatest alignment supported by the implementation in all contexts, which is equal to
alignof(std::max_align_t)
.
Where 'all contexts' includes new T
. So, the alignment of the pointer returned by operator new(std::size_t)
must be >= alignof(std::max_align_t)
.
This was unchanged in C++17, however new T
can now call operator new(std::size_t, std::align_val_t)
, which I guess theoretically allows __STDCPP_DEFAULT_NEW_ALIGNMENT__ < alignof(std::max_align_t)
(calling the new-extended operator new when you do new std::max_align_t
), but that would not be backwards compatible and doesn't seem to be intentionally allowed behaviour.
Also an alignment greater than alignof(std::max_align_t)
is called an extended alignment, and an alignment greater than __STDCPP_DEFAULT_NEW_ALIGNMENT__
is called a new-extended alignment, both defined in [basic.align]p3. It seems like the intention is that new-extended alignments are a subset of extended alignments (or at least overaligned types, which std::max_align_t
isn't), which would require __STDCPP_DEFAULT_NEW_ALIGNMENT__ >= alignof(std::max_align_t)
.