Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
485 views
in Technique[技术] by (71.8m points)

c++ - gcc over-aligned new support (alignas )

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

From gcc's manual:

-faligned-new
Enable support for C++17 new of types that require more alignment than void* ::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 of alignof(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 type std::size_t whose value is the alignment guaranteed by a call to operator new(std::size_t) or operator new[](std::size_t). [ Note: Larger alignments will be passed to operator 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 type std::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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...