Sunday, 10 August 2014

Return value optimization

RVO is a form of copy elision compiler optimization, where unnecessary copies of objects are eliminated.

As usual we let the example speak for itself:

#include <iostream>
using namespace std;

class C
{
public:
    C()
    {
        cout << "Constructor" << endl;
    }

    ~C()
    {
        cout << "Destructor" << endl;
    }

    C(C&& other)
    {
        cout << "Move constructor" << endl;
    }

    C(const C& other)
    {
        cout << "Copy constructor" << endl;
    }
};

C f1()
{
    C c;
    return c;
}

int main()
{
    C c1 = f1();
    return 0;
}


When optimization is disabled ("debug" builds in Visual Studio), this gives:

Constructor
Move constructor
Destructor
Destructor


The first constructor is called from f1(). The move constructor is called at return c;. The first destructor is called when the local c goes out of scope. (Move constructor does not really mean "move", it's a name for the constructor that takes rvalue references.) The last destructor is called when the c1 goes out of scope.

That's pretty much a lot of stuff going on there. With optimization ("release" builds), however, we are left with:

Constructor
Destructor


A much leaner output! So, don't worry too much about returning objects by value from functions - write for clarity instead!

No comments:

Post a Comment