5

我发现英特尔编译器不会为 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 中,他们给出的示例有一个复制构造函数。那么,这是英特尔编译器的“错误”还是符合标准的实现?

4

1 回答 1

1

由于违反了单一定义规则,该程序会导致未定义的行为,无需诊断。

在按值返回时使用复制构造函数——即使发生复制省略

使用 odr 的非内联函数意味着该函数的一个定义必须出现在程序中。但是,您没有提供任何内容,并且您对复制构造函数的声明会抑制编译器生成的定义。

于 2015-03-04T13:31:36.277 回答