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

倾然丶 夕夏残阳落幕 提交于 2021-02-18 11:54:56

问题


In Visual Studio, when compiling 64-bit:

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

So although std::max_align_t indicates that implementations of new should return pointers aligned to a multiple of 8 bytes, allocations with an alignment requirement of 16 bytes don't call the void* operator new (std::size_t count, std::align_val_t); method but call void* operator new (std::size_t count); (see https://en.cppreference.com/w/cpp/memory/new/operator_new) and expect them to return a pointer aligned on 16 bytes.

So allocating a struct defined like this:

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

will call the standard operator new (without std::align_val_t argument) and expect it to be aligned on 16 bytes, while std::max_align_t only specifies that it should be aligned on 8 bytes.

This means that when overruling the new operators, you are forced to align everything on at least 16 bytes, even if 8 bytes would be sufficient.

  • Am I missing something?
  • Is this an error in the way Visual Studio implements C++/STL?
  • Or is this an error in the C++/STL standard?

回答1:


There are two layers of over-aligned types in C++17: extended and new-extended. std::max_align_t defines the largest alignment that is not extended, and __STDCPP_DEFAULT_NEW_ALIGNMENT__ defines the largest alignment that is not new-extended.

New-extended alignment, as the name suggests, is about the alignment of things you allocate with new.

Basically, the regular operator new will return memory suitable for any object up to the new-extended alignment size. Any greater alignment prefers the use of operator new overloads that specify the alignment of the type being created. And of course, are conditionally supported just like over-aligned types in general. The same goes for the operator delete calls to destroy the memory associated with such types.

What Visual Studio is saying is that the maximum alignment that is not considered over-aligned is 8-byte, but the alignment for memory allocated by operator new is 16-byte.


This means that when overruling the new operators, you are forced to align everything on at least 16 bytes, even if 8 bytes would be sufficient.

Essentially, yes. There's no way to request that the implementation tell you what alignment is being requested with the raw operator new/delete overloads.

Now, you can, on an object-by-object basis, overload that object's operator new to invoke the alignment-specific operator new directly. But you can't make the compiler do so.



来源:https://stackoverflow.com/questions/56171482/why-does-the-c-standard-allow-stdmax-align-t-and-stdcpp-default-new-alignm

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!