I'm trying to reason why a reasonably good C++ 11 compiler (clang) is not optimizing this code, and wondering if anybody here has opinions.
#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;
}
If I run this with #define SLOW
commented out and optimized with -s
I get
Hello World!
A move
A d'tor
0x7fff5fbff9f0
A d'tor
which is expected.
If I run this with #define SLOW
enabled and optimized with -s
I get:
Hello World!
A copy
A move
A d'tor
A d'tor
0x7fff5fbff9e8
A d'tor
Which obviously isn't as nice. So the question is:
Why am I not seeing a NRVO optimization applied in the "SLOW" case? I know that the compiler is not required to apply NRVO, but this would seem to be such a common simple case.
In general I try to encourage code of the "SLOW" style because I find it much easier to debug.