0

Will return-value optimization occur in the following example? (Possibly compiler-dependent question. In which case I suppose I'm wondering for "typical" modern compilers like recent clang/gcc.)

Blah factory() {
  return Blah();
}

void func() {
  Blah blah;
  if (condition) {
    blah = factory();
    blah.DoSomething();
  } else {
    blah = factory();
    blah.DoSomethingElse();
  }
  blah.DoOneMoreThing();
}

I know I'm not explicitly constructing the object in the same line as calling the factory function, but a smart enough compiler could definitely optimize away the copies in the above example (since the instance blah has not been touched prior to being set to factory()).

If RVO will indeed not occur, is there some way to avoid the copies without changing factory?

Josh Burkart
  • 438
  • 4
  • 12
  • 2
    This code [looks very familiar](https://www.youtube.com/watch?v=3taEuL4EHAg). – Kerrek SB Nov 17 '14 at 23:49
  • 1
    Why not: `Blah x = factory(); if (condition) { x.f(); } else { x.g(); } x.h();`? – Kerrek SB Nov 17 '14 at 23:50
  • I asked recently a very similar question, http://stackoverflow.com/questions/26959846/move-semantics-in-eigen and it seems that if you implement a copy-and-swap copy ctor then you'll be fine. Definitely if you write `Blax x = factory();` then copy elision will kick in. – vsoftco Nov 17 '14 at 23:52
  • I'm [coming to the conclusion](http://stackoverflow.com/questions/25963685/why-does-visual-studio-not-perform-return-value-optimization-rvo-in-this-case) that your best bet is to ensure `Blah` has a cheap move constructor and move assignment operator and then even if the compiler fails to elide the moves it won't matter too much. It is normally easy enough to make something cheap to move and if not just put it in a `unique_ptr`. – Chris Drew Nov 18 '14 at 00:19
  • @chris-drew I went with the unique_ptr method, thanks. – Josh Burkart Nov 19 '14 at 19:12

1 Answers1

1

There won't be any return value optimization in your program, because Blah blah; calls the default constructor which may have side effects (such as printing a message or locking a mutex), and the C++ compiler is not allowed to optimize that away. As soon as blah has been default-constructed, it can't be constructed again in the assignments below, but the return value optimization would require construction.

However, if your constructor and assignment operator definitions are available for the compiler, then it may optimize the generated code so that it may eventually end up the same as a the copy constructor would end up. But this is not guaranteed.

pts
  • 80,836
  • 20
  • 110
  • 183