我在查找有关GCC的对齐新警告和gcc -faligned-new选项的更多信息时遇到了一些困难。在gcc 7.2.0上编译(没有--std = c ++ 17)并尝试定义一个对齐的结构,例如:
struct alignas(64) Foo { int x; }
做一个普通的老人:
Foo * f = new Foo();
给我以下警告和建议:
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
据我所知,默认情况下new
只返回内存对齐alignof( std::max_align_t )
的内存(对我而言是16),但我不清楚的是,如果我传递了-faligned-new, gcc现在代表我强制执行new
的正确新对齐?
不幸的是,关于这方面的gcc文档非常缺乏。
答案 0 :(得分:4)
来自gcc's manual:
-faligned新
启用对需要比new
提供的更多对齐的C ++ 17void* ::operator new(std::size_t)
类型的支持。可以使用诸如-faligned-new = 32之类的数字参数来指定该函数提供的对齐(以字节为单位),但很少有用户需要覆盖默认值alignof(std::max_align_t)
。
这意味着-faligned-new只会在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
。如果已分配对象的类型具有新扩展对齐,则下一个参数是类型的对齐,并且类型为std::align_val_t
。
因此,对于使用C ++ 17或-faligned-new的情况,由于Foo
具有新扩展对齐,Foo* f = new Foo();
会将void* operator new(size_t, align_val_t)
调用为分配内存并返回指向在{64}字节边界上正确对齐的Foo
对象的指针。根据早先的标准并非如此。