Search code examples
c++rvonrvo

Does introducing a new variable defeat return value optimisation?


We all know that

Foo returnAFoo()
{
    return Foo();
}

will be compiled with return value optimisation so a value copy will not be taken even if the copy constructor of Foo has side effects. But will

Foo returnAFoo()
{
    Foo f = Foo();
    return f;
}

too? The second construct can be helpful when debugging. But am I throwing away an important optimisation in doing so? Perhaps I need to write an explicit move constructor?


Solution

  • No. Copy elision can still be applied here. In this specific case, it is called NRVO (named return value optimisation). You don't need a move constructor for copy elision to be performed; copy elision has been in the standard since C++98/03, when we only had copy constructors.

    To maximise your chance of copy elision being used, you should make sure that either: all code paths return the same object (NRVO) or all code paths return a temporary object (RVO).

    If you mix and match NRVO and RVO inside the same function it becomes hard to apply the optimisation.


    Sample code demonstrating NRVO.