__STDCPP_DEFAULT_NEW_ALIGNMENT__ 和 alignof(std::max_align_t) 之间的顺序
Order between __STDCPP_DEFAULT_NEW_ALIGNMENT__ and alignof(std::max_align_t)
在 x86-64/Linux 上使用 GCC 和 Clang alignof(std::max_align_t)
和 __STDCPP_DEFAULT_NEW_ALIGNMENT__
都等于 16
。
在 x86-64/Windows 上使用 MSVC alignof(std::max_align_t)
是 8
并且 __STDCPP_DEFAULT_NEW_ALIGNMENT__
是 16
。
标准定义了[basic.align]/3中这些量对应的两个术语:
An extended alignment is represented by an alignment greater than alignof(std::max_align_t)
. [...] A type having an extended alignment requirement is an over-aligned type. [...] A new-extended alignment is represented by an alignment greater than __STDCPP_DEFAULT_NEW_ALIGNMENT__
.
我看不出这意味着两个值之间的任何排序,除非我将术语“new-extended”解释为暗示“extended " 从拼写。
是否允许符合 C++ 标准的实现
alignof(std::max_align_t) > __STDCPP_DEFAULT_NEW_ALIGNMENT__
?
如果是,这是否意味着对象创建通过
auto x = ::new(::operator new(sizeof(T))) T;
可能是某些非过度对齐类型的未定义行为 T
?
std::max_align_t
: 最大标量类型的对齐方式
__STDCPP_DEFAULT_NEW_ALIGNMENT__
:分配内存的对齐方式
如果我读的标准是正确的,新的扩展对齐是指 void* operator new( std::size_t count, std::align_val_t al);
的所有变体(那些带有 std::align_val_t
的变体)。
所以假设8的__STDCPP_DEFAULT_NEW_ALIGNMENT__
和16的std::max_align_t
,分配long double就得调用::operator new(16, std::align_val_t(16));
。您的编译器必须在您不注意的情况下为您做一些事情。
实际上,我相信有 linux 实现可以保证新的对齐方式为 8。(moz)jemalloc is one of them, for which this github-issue 似乎确认最小对齐方式是 8 而不是 16。(我没有'找到关于它的官方文档)
如果你想使用这样的实现,你必须更新 __STDCPP_DEFAULT_NEW_ALIGNMENT__
常量,有关更多详细信息,请参阅我的问题之一:.
为了回答你的最后一个问题,我读到 auto x = ::new(::operator new(sizeof(T))) T;
是明确调用 operator new 而不是简单地做 new T
,在这种情况下,如果 T 需要对齐,我会假设你确实有 UB大于默认的新对齐方式。请注意,如果两个常量相等,这也成立,因为您可以将 alignas
添加到 class 以更改对齐方式。
使用这些 classes 需要格外小心,因为在与 std::vector
一起使用时使用自定义分配器。
在 x86-64/Linux 上使用 GCC 和 Clang alignof(std::max_align_t)
和 __STDCPP_DEFAULT_NEW_ALIGNMENT__
都等于 16
。
在 x86-64/Windows 上使用 MSVC alignof(std::max_align_t)
是 8
并且 __STDCPP_DEFAULT_NEW_ALIGNMENT__
是 16
。
标准定义了[basic.align]/3中这些量对应的两个术语:
An extended alignment is represented by an alignment greater than
alignof(std::max_align_t)
. [...] A type having an extended alignment requirement is an over-aligned type. [...] A new-extended alignment is represented by an alignment greater than__STDCPP_DEFAULT_NEW_ALIGNMENT__
.
我看不出这意味着两个值之间的任何排序,除非我将术语“new-extended”解释为暗示“extended " 从拼写。
是否允许符合 C++ 标准的实现
alignof(std::max_align_t) > __STDCPP_DEFAULT_NEW_ALIGNMENT__
?
如果是,这是否意味着对象创建通过
auto x = ::new(::operator new(sizeof(T))) T;
可能是某些非过度对齐类型的未定义行为 T
?
std::max_align_t
: 最大标量类型的对齐方式__STDCPP_DEFAULT_NEW_ALIGNMENT__
:分配内存的对齐方式
如果我读的标准是正确的,新的扩展对齐是指 void* operator new( std::size_t count, std::align_val_t al);
的所有变体(那些带有 std::align_val_t
的变体)。
所以假设8的__STDCPP_DEFAULT_NEW_ALIGNMENT__
和16的std::max_align_t
,分配long double就得调用::operator new(16, std::align_val_t(16));
。您的编译器必须在您不注意的情况下为您做一些事情。
实际上,我相信有 linux 实现可以保证新的对齐方式为 8。(moz)jemalloc is one of them, for which this github-issue 似乎确认最小对齐方式是 8 而不是 16。(我没有'找到关于它的官方文档)
如果你想使用这样的实现,你必须更新 __STDCPP_DEFAULT_NEW_ALIGNMENT__
常量,有关更多详细信息,请参阅我的问题之一:
为了回答你的最后一个问题,我读到 auto x = ::new(::operator new(sizeof(T))) T;
是明确调用 operator new 而不是简单地做 new T
,在这种情况下,如果 T 需要对齐,我会假设你确实有 UB大于默认的新对齐方式。请注意,如果两个常量相等,这也成立,因为您可以将 alignas
添加到 class 以更改对齐方式。
使用这些 classes 需要格外小心,因为在与 std::vector
一起使用时使用自定义分配器。