c++c++17language-lawyermemory-alignment

Is __STDCPP_DEFAULT_NEW_ALIGNMENT__ >= alignof(std::max_align_t)?


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.


Solution

  • 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).