问题
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