命名返回值优化

本文探讨了C++中命名返回值优化(NRVO)的行为,并通过具体示例展示了编译器如何优化对象的构造过程。文章还介绍了如何禁用此优化以观察拷贝构造函数的调用。
今天突然想到一个问题,如果在函数fun中定义一个局部对象a,然后返回该局部对象a给调用函数main,会不会专门为返回值再生成一个对象?
即如以下代码所示,一共会调用多少次构造函数和析构函数呢?
class A
{
 
  public:
       A(){cout<<"constructor"<<endl;};
       A(const A &a){cout<<"copyconstructor"<<endl;};
       ~A(){cout<<"destructor"<<endl;};
};     

A fun()
{
   cout<<"infun"<<endl;
    A a;
   cout<<"returningfun"<<endl;
    returna;
 

int main()
{
   cout<<"inmain"<<endl;
    Aa=fun();
   cout<<"returningmain"<<endl;
    return0;


一开始我认为这段程序至少需要调用两次构造函数生成两个对象,分别是
fun: A a;
main: A a=fun();
疑惑的是在fun返回a的时候,会不会构造一个返回值对象?

使用G++ 4.4进行编译,g++ testReturn.cpp
执行,打印结果:
in main
in fun
constructor
returning fun
returning main
destructor

居然只调用了一次构造函数!!!
而且构造函数是在fun中调用,析构函数是在main中调用
显然,g++进行了编译优化直接使用了fun()的返回对象,而没有在main中构造新的对象
但是,如果我在构造函数中有很重要的事情要做呢,比如需要new 一个对象啥的,那该怎么办呢
去掉g++的编译优化选项?g++ -O0 testReturn.cpp
得到的结果仍然是:
in main
in fun
constructor
returning fun
returning main
destructor
google了一下,发现这是一个称为命名返回值优化的问题,而且g++的这个编译优化竟然没有直接的关闭方法,在一个163博客上看到了相关线索,提到了
Joe Buck <Joe.Buck@synopsys.COM> writes:



> On Wed, Nov 07, 2007 at 07:48:53AM -0800, Ian Lance Taylor wrote:

> > "Debarshi Sanyal" <debarshisanyal@gmail.com> writes:

> > 

> > >    Is there any way to turn off "named return value optimization"

> > > (NRVO) while compiling a C++ program with g++?

> > 

> > This question is not appropriate for gcc@gcc.gnu.org, which is for

> > developers of gcc.  It is appropriate for gcc-help@gcc.gnu.org.

> > Please take any followups to that mailing list.  Thanks.

> > 

> > The answer to your question is no.  g++ will always implement NRVO

> > when possible.

> 

> You forgot about -fno-elide-constructors , Ian.  I've needed it in

> the past to work around a bug in profiling; there's a PR for this.



Ah, tricky.  Thanks.



Ian
尝试了一下,g++ -fno-elide-constructors testReturn.cpp ,执行结果:
in main
in fun
constructor
returning fun
copy constructor
destructor
copy constructor
destructor
returning main
destructor

终于看到main中的拷贝构造函数了!
不过在fun返回的时候,程序并没有构造一个返回值对象,因此只调用了两次构造函数
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值