適度に優れた C++ 11 コンパイラ (clang) がこのコードを最適化しない理由を説明しようとしています。
#include <iostream>
#define SLOW
struct A {
A() {}
~A() { std::cout << "A d'tor\n"; }
A(const A&) { std::cout << "A copy\n"; }
A(A&&) { std::cout << "A move\n"; }
A &operator =(A) { std::cout << "A copy assignment\n"; return *this; }
};
struct B {
// Using move on a sink.
// Nice talk at Going Native 2013 by Sean Parent.
B(A foo) : a_(std::move(foo)) {}
A a_;
};
A MakeA() {
return A();
}
B MakeB() {
// The key bits are in here
#ifdef SLOW
A a(MakeA());
return B(a);
#else
return B(MakeA());
#endif
}
int main() {
std::cout << "Hello World!\n";
B obj = MakeB();
std::cout << &obj << "\n";
return 0;
}
これを#define SLOW
コメントアウトして最適化して実行すると-s
、
Hello World!
A move
A d'tor
0x7fff5fbff9f0
A d'tor
これは予想されます。
これを#define SLOW
有効にして最適化して実行すると、次の-s
ようになります。
Hello World!
A copy
A move
A d'tor
A d'tor
0x7fff5fbff9e8
A d'tor
これは明らかにそれほど良くありません。質問は次のとおりです。
「SLOW」の場合に適用された NRVO 最適化が表示されないのはなぜですか? コンパイラが NRVO を適用する必要がないことは知っていますが、これは非常に一般的な単純なケースのようです。
一般的に、私は「SLOW」スタイルのコードを推奨するようにしています。これは、デバッグがはるかに簡単だからです。