问题
I'm having some difficulty finding more information about GCC's aligned-new warning and the gcc -faligned-new option. Compiling on gcc 7.2.0 (without --std=c++17) and trying to define an aligned struct such as:
struct alignas(64) Foo { int x; }
Just doing a plain old:
Foo * f = new Foo();
Gives me the following warning and suggestion:
alignas.cpp:36:25: warning: ‘new’ of type ‘Foo’ with extended alignment 64 [-Waligned-new=]
Foo * f = new Foo();
^
alignas.cpp:36:25: note: uses ‘void* operator new(long unsigned int)’, which does not have an alignment parameter
alignas.cpp:36:25: note: use ‘-faligned-new’ to enable C++17 over-aligned new support
I understand that by default new
will only return memory aligned up to alignof( std::max_align_t )
( which is 16 for me ), but what's not clear to me is that if I pass -faligned-new, will gcc now enforce proper new alignment of new
on my behalf?
Unfortunately the gcc documentation on this is extremely lacking.
回答1:
From gcc's manual:
-faligned-new
Enable support for C++17new
of types that require more alignment thanvoid* ::operator new(std::size_t)
provides. A numeric argument such as -faligned-new=32 can be used to specify how much alignment (in bytes) is provided by that function, but few users will need to override the default ofalignof(std::max_align_t)
.
This implies that -faligned-new simply makes the aligned-new features added in P0035R4 available without fully enabling C++17 support.
The relevant bits from the C++ standard:
From [cpp.predefined]:
__STDCPP_DEFAULT_NEW_ALIGNMENT__
An integer literal of typestd::size_t
whose value is the alignment guaranteed by a call tooperator new(std::size_t)
oroperator new[](std::size_t)
. [ Note: Larger alignments will be passed tooperator new(std::size_t, std::align_val_t)
, etc. (8.3.4). — end note ]
From [basic.align/3]:
A new-extended alignment is represented by an alignment greater than
__STDCPP_DEFAULT_NEW_ALIGNMENT__
And from [expr.new/14]:
Overload resolution is performed on a function call created by assembling an argument list. The first argument is the amount of space requested, and has type
std::size_t
. If the type of the allocated object has new-extended alignment, the next argument is the type’s alignment, and has typestd::align_val_t
.
So in your case with C++17 or -faligned-new, since Foo
has new-extended alignment, Foo* f = new Foo();
will call void* operator new(size_t, align_val_t)
to allocate memory and return a pointer to a Foo
object that is properly aligned on a 64-byte boundary. Under earlier standards that was not the case.
来源:https://stackoverflow.com/questions/49373287/gcc-over-aligned-new-support-alignas