为什么NRVO不适用于此?

时间:2013-04-16 13:32:53

标签: c++ visual-studio-2010 nrvo

在VS2010中运行此代码时,未应用NRVO。

#include <stdio.h>

class A
{
    public:

    A() { printf( "I am in constructor\n" ); }
    A(const A& a) { printf( "I am in copy constructor\n" ); }
    ~A() { printf( "I am in destructor\n" ); }
    int i;       
};

A f(int j)
{
    A a;
    if ( j )  return a;
    a.i = j;
    return a; 
}

int main()
{
    A a;
    a = f(5);
}

编辑:这与析构函数有关。当我评论它的线时,使用NRVO。但为什么会这样呢?

2 个答案:

答案 0 :(得分:4)

  

为什么不在这里应用NRVO?

如果这纯粹是对你的好奇,并且你想知道VC10如何在算法上决定是否执行NRVO,那么唯一能够可靠地回答这个问题的人就是那些知道VC10如何在内部工作的人 - 那些写它的人

根据C ++ 11标准,根据C ++ 11标准,编译器允许在这种情况下执行NRVO,而不这样做只是编译器的决定 - 不是由于任何有效性约束。根据第12.8 / 31段:

  

[...]在下列情况下允许复制/移动操作(称为复制省略)   可以合并以消除多个副本):

     

- 在具有类返回类型的函数的返回语句中,当表达式是a的名称时   具有相同cv-unqualified的非易失性自动对象(函数或catch子句参数除外)   键入函数返回类型,可以通过构造省略复制/移动操作   自动对象直接进入函数的返回值

     

[...]

但是,如果您要求强制您的编译器执行NRVO,那么答案是“您不能”。

完全由编制者自行决定是否申请NRVO。你不能指望它,你不能指望它被执行。据我所知,这是所谓“ as-if ”规则的唯一例外。

这就是说,当你提高优化水平时,获得NRVO的可能性会增加。

答案 1 :(得分:0)

我不知道您在您的环境中看到了什么,但这在GCC中正常运行(例如see here):

<强>正常:

I am in constructor
I am in constructor
I am in destructor
I am in destructor

使用-fno-elide-constructors

I am in constructor
I am in constructor
I am in copy constructor
I am in destructor
I am in destructor
I am in destructor