【发布时间】:2015-07-20 13:34:08
【问题描述】:
我编写了一个程序来评估这样做之间的性能差异:
func3(func2(func1()));
对比这个:
retval1 = func1();
retval2 = func2(retval1);
func3(retval2);
我更喜欢后者,因为它的可读性和调试方便,我想知道编译器 (MSVC 12.0) 是否会优化发布版本中的中间对象。我的测试程序是这样的:
#include <iostream>
using namespace std;
struct Indicator {
Indicator() {cout << "Default constructor" << endl;}
Indicator(const Indicator& other) {cout << "Copy constructor" << endl;}
const Indicator& operator=(const Indicator& other) {cout << "Assignment operator" << endl;}
~Indicator() {cout << "Destructor" << endl;}
};
Indicator func1()
{return Indicator();}
Indicator func2(Indicator&& i)
{return std::move(i);}
Indicator func3(Indicator&& i)
{return std::move(i);}
int main() {
Indicator i = func3(func2(func1()));
cout << &i << endl;
return 0;
}
我惊讶地发现,即使使用 -O2,仍然会创建三个 Indicator 实例:
Default constructor
Copy constructor
Copy constructor
Destructor
Destructor
00000000002EFC70
Destructor
Press <RETURN> to close this window...
这与我对移动语义的理解相冲突,即在这种情况下应该只创建一个Indicator 的实例。我还认为编译器应该能够将 NRVO 用于链式函数调用。有人可以向我解释这里发生了什么吗?
【问题讨论】:
标签: c++ optimization