#cpp RVO (Return Value Optimization), NRVO (Named RVO) - visual studio

1 minute read

class RVO
{
public:
    RVO()               { PrintLine("constructor"); }
    RVO(const RVO& rhs) { PrintLine("copy constructor"); }
    ~RVO()              { PrintLine("destructor"); }

    RVO& operator=(const RVO& rhs)
    {
        PrintLine("assign operator");
        return *this;
    }

    int dummy;
};

RVO MyMethod (int i)
{
    RVO rvo;
    rvo.dummy = i;
    return rvo;
}

int main()
{
    RVO rvo;
    rvo = MyMethod(5);

    return 0;
}

MyMethod가 값으로 객체를 리턴(return by value)하는 게 포인트다. 설명이고 자시고 출력 값부터 보자. 소스 코드는 MSDN 예제 코드를 조금 고쳤다.

disable NRVO (/Od)

constructor
constructor
copy constructor - temporary object
destructor
assign operator
destructor - temporary object
destructor

함수에서 객체 인스턴스를 리턴할 때 어떤 일이 일어날까? 리턴할 때 임시 객체(temporary object)를 복사 생성자로 만들어서 리턴한다.

enable NRVO (/O1, /O2, /Ox, /Og)

constructor
constructor
assign operator
destructor
destructor

NRVO를 켜주면 임시 객체를 만들지 않고 바로 할당한다. 이런 임시 객체 생성을 막아주는 기술이 바로 NRVO이다.

그럼 RVO와 NRVO 차이는 뭘까?

BigData GetData()
{
    // RVO
    return BigData();
}

BigData GetData()
{
    // NRVO
    BigData data;
    return data;
}

RVO는 return문에서 객체를 생성해서 리턴할 경우 임시 객체 생성을 막아주는 기술이고 NRVO는 return문 이전에 생성한 객체를 리턴했을때 임시 객체 생성을 막아주는 기술이다. 당연 컴파일러 제작자로서 RVO가 구현 난이도가 낮아서 VS2005 이전부터 지원했고(2003부터 구현됐다는 웹페이지는 있는데, MSDN에서는 못 찾겠다.) NRVO는 VS2005부터 지원한다.

참고로 최적화를 사용 안하는 (/Od) 옵션 빼고는 다 NRVO 기술을 사용한다. RVO는 최적화 옵션에 상관없이 무조건 사용.

참고 : Named Return Value Optimization in Visual C++ 2005 - MSDN