4

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?

Jarod42
  • 203,559
  • 14
  • 181
  • 302
P45 Imminent
  • 8,319
  • 4
  • 35
  • 78
  • 1
    Note there is a specific variant of the return value optimisation called *Named* Return Value Optimisation (NRVO). It is sometimes harder than "normal" RVO, but in general compilers can do it. Both are different completely from moving an object. If you have an explicit copy constructor/assignment operator, then you need to explicitly define the move constructor/assignment operator too. – BoBTFish Mar 23 '16 at 08:46
  • @BoBTFish: Please put that as an answer: I would accept it. – P45 Imminent Mar 23 '16 at 08:46
  • 1
    http://cpp.sh/9yvs – Humam Helfawi Mar 23 '16 at 08:47
  • @P45 I can't be bothered (/have work I really should be doing) to flesh it out with examples, references, etc. Don't worry, it won't take long for someone else to do it. (And don't feel you have to accept an incomplete answer just because it is the only one). – BoBTFish Mar 23 '16 at 08:48
  • @BoBTFish Copy elision works just fine without move operations. Can you clarify? – Angew is no longer proud of SO Mar 23 '16 at 08:49

1 Answers1

7

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.

Simple
  • 13,992
  • 2
  • 47
  • 47