为什么C 标准允许STD :: MAX_ALIGN_T和__STDCPP_DEFAULT_NEW_ALIGNMENT

Why does the C++ standard allow std::max_align_t and __STDCPP_DEFAULT_NEW_ALIGNMENT__ to be inconsistent?

本文关键字:STDCPP ALIGNMENT NEW DEFAULT ALIGN MAX 标准 STD 为什么      更新时间:2023-10-16

在Visual Studio中,编译64位时:

  • sizeof(std::max_align_t)是8
  • __STDCPP_DEFAULT_NEW_ALIGNMENT__是16

因此,尽管std::max_align_t表明new的实现应返回与8个字节的倍数对齐的指示器,但分配要求16字节的分配不调用void* operator new (std::size_t count, std::align_val_t);方法,但请致电void* operator new (std::size_t count);(请参阅https://en.cpppreference。com/w/cpp/note/new/operator_new(,并期望它们返回16字节上对齐的指针。

因此分配这样定义的结构:

struct alignas(16) S {double m_value;};

将调用标准运算符new(无std::align_val_t参数(,并期望将其对准16个字节,而std::max_align_t仅指定它应在8个字节上对齐。

这意味着,当覆盖new操作员时,即使8个字节足够,您也会被迫在至少16个字节上对齐所有内容。

  • 我错过了什么吗?
  • 这是Visual Studio实现C /STL的方式的错误吗?
  • 这是C /STL标准中的错误?

C 17中有两层过度对准的类型:扩展和新扩展。std::max_align_t定义了未扩展的最大对齐,__STDCPP_DEFAULT_NEW_ALIGNMENT__定义了不是新扩展的最大对齐。

顾名思义,新扩展的对齐方式是关于您与new分配的事物的对齐。

基本上,常规operator new将返回适合任何对象的内存,直至新扩展的对齐尺寸。任何更大的一致性都更喜欢使用operator new过载来指定所创建类型的对齐。当然,就像一般而言的过度对准类型一样,有条件地受到有条件的支持。operator delete调用以破坏与此类类型相关的内存的调用也是如此。

Visual Studio在说什么是不认为过度对准的最大对齐是8字节,但是由operator new分配的内存对齐是16字节。


这意味着,当覆盖new操作员时,即使8个字节足够,您也会被迫在至少16个字节上对齐所有内容。

本质上,是的。没有办法要求实施告诉您与RAW operator new/delete超载的要求。

现在,您可以以对象为基础的对象过载该对象的operator new来直接调用特定于对齐的operator new。但是您不能让编译器这样做。