我试图解释为什么一个相当好的 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
这显然不是那么好。所以问题是:
为什么我没有看到在“慢”情况下应用了 NRVO 优化?我知道编译器不需要应用 NRVO,但这似乎是一个常见的简单案例。
一般来说,我尝试鼓励使用“SLOW”风格的代码,因为我发现它更容易调试。