gcc过度对齐的新支持(alignas)

Byt*_*e95 9 c++ gcc gcc-warning alignas

我在查找有关GCC的对齐新警告和gcc -faligned-new选项的更多信息时遇到了一些困难.在gcc 7.2.0上编译(没有--std = c ++ 17)并尝试定义一个对齐的结构,例如:

struct alignas(64) Foo { int x; }
Run Code Online (Sandbox Code Playgroud)

做一个简单的旧:

Foo * f = new Foo();
Run Code Online (Sandbox Code Playgroud)

给我以下警告和建议:

 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
Run Code Online (Sandbox Code Playgroud)

据我所知,默认情况下new只返回内存对齐alignof( std::max_align_t )(对我而言是16),但我不清楚的是,如果我传递-faligned-new,gcc现在会new代表我强制执行新的对齐吗?

不幸的是,关于这个的gcc文档非常缺乏.

Mil*_*nek 7

GCC手册

-faligned新
启用C ++ 17支持new的需要多个对准比类型void* ::operator new(std::size_t)提供。可以使用-faligned-new = 32之类的数字参数来指定该函数提供多少对齐(以字节为单位),但是很少有用户需要覆盖默认值alignof(std::max_align_t)

这意味着-faligned全新只是使中添加的排列成行的新功能P0035R4可用而不完全启用C ++ 17的支持。

C ++标准中的相关位:
从[cpp.predefined]:

__STDCPP_DEFAULT_NEW_ALIGNMENT__
类型的整数文字,std::size_t其值是通过调用operator new(std::size_t)或来保证的对齐方式operator new[](std::size_t)。[注意:较大的对齐方式将传递给operator new(std::size_t, std::align_val_t),等等(8.3.4)。—尾注]

来自[basic.align / 3]:

新扩展的取向由取向大于表示__STDCPP_DEFAULT_NEW_ALIGNMENT__

从[expr.new/14]中:

对通过组合参数列表创建的函数调用执行重载解析。第一个参数是请求的空间量,类型为std::size_t。如果分配的对象的类型具有新扩展的对齐方式,则下一个参数是该类型的对齐方式,并且具有type std::align_val_t


因此,在您使用C ++ 17或-faligned-new的情况下,由于Foo具有new-extended对齐Foo* f = new Foo();将调用void* operator new(size_t, align_val_t)分配内存并返回指向Foo在64字节边界上正确对齐的对象的指针。在较早的标准,情况并非如此。