Intel コンパイラが 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 では、彼らが提供する例にはコピー コンストラクターがあります。では、これは Intel コンパイラの「バグ」なのか、それとも標準に準拠した実装なのか?