A Look into Return Value Optimization of C++

This is the code we will be looking at.

Foo is very simple. It prints on construction, copy and destruction.

See it in action

Now if you run it (compile with no special flags). You will get

foo constructed
foo destructed

You can see that there was only one Foo instance ever constructed and never copied. If you turn copy elision off, by doing g++ -fno-elide-constructors, you will get

foo constructed
foo copied
foo destructed
foo copied
foo destructed
foo destructed

Dig into the assembly

How did the compiler get rid of the copies?
In order to really see what’s happening, we need to look at the assembly. You can get the complete assembly from https://godbolt.org/.

With RVO (adding code in Medium is terrible, see the code from my blog https://blog.the-pans.com/rvo/):

The gist is that the callee construct an object in caller’s stack frame, by reading %rdi for the address. In this way, no copy is needed.

The one without RVO is much longer and less interesting.

gdb is very useful in understanding exactly what each assembly instruction is doing. Here are a few useful commands:

  • disassemble to show the assembly
  • nexti to execute one line
  • x/xg to exam the memory address, which can check registers as well

Originally published at blog.the-pans.com on January 6, 2018.

Software Engineer at Facebook working on cache infrastructure

Software Engineer at Facebook working on cache infrastructure