我发现英特尔编译器不会为std :: array对象生成返回值优化。以下代码恰好在我的程序的内部循环中没有进行优化。
std::array<double, 45> f(const std::array<double, 45>& y) {
auto dy_dt = std::array<double, 45>( );
...
return dy_dt;
}
我已经发现这种行为来自于我的标准库实现没有为std :: array显式定义复制构造函数这一事实。以下代码演示了:
class Test {
public:
Test() = default;
Test(const Test& x);
};
Test f() {
auto x = Test( );
return x;
}
使用
编译时icpc -c -std=c++11 -qopt-report=2 test.cpp -o test.o
报告文件显示
INLINE REPORT: (f(Test *)) [1] main.cpp(7,10)
证明编译器生成RVO(f的签名已更改,因此它可以将新创建的对象放在调用站点的堆栈上)。但是,如果您注释掉声明Test(const Test& x);
的行,则报告文件会显示
INLINE REPORT: (f()) [1] main.cpp(7,10)
证明没有生成RVO。
在定义RVO的C ++ 11标准的12.8.31中,他们给出的示例有一个复制构造函数。那么,这是一个&#34; bug&#34;英特尔编译器或符合标准的实现?
答案 0 :(得分:1)
由于违反了One Definition Rule,该程序会导致未定义的行为而无需诊断。
按值返回时,复制构造函数 odr-used - even if copy elision takes place。
odr-used 的非内联函数意味着函数的一个定义必须出现在程序中。但是,您没有提供任何内容,并且您对复制构造函数的声明会抑制编译器生成的定义。