命名返回值优化

今天突然想到一个问题,如果在函数fun中定义一个局部对象a,然后返回该局部对象a给调用函数main,会不会专门为返回值再生成一个对象?
即如以下代码所示,一共会调用多少次构造函数和析构函数呢?
class A
{
 
  public:
       A(){cout<<"constructor"<        A(const A &a){cout<<"copyconstructor"<        ~A(){cout<<"destructor"< };     

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

int main()
{
   cout<<"inmain"<     Aa=fun();
   cout<<"returningmain"<     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  writes:



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

> > "Debarshi Sanyal"  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 [email protected], which is for

> > developers of gcc.  It is appropriate for [email protected].

> > 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返回的时候,程序并没有构造一个返回值对象,因此只调用了两次构造函数

你可能感兴趣的:(C/C++)