命名返回值优化

本文探讨了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返回的时候,程序并没有构造一个返回值对象,因此只调用了两次构造函数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值