2

Example:

A myfunction() { return A(); }
A a = myfunction(); // default ctor only (return value optimization)
a = myfunction(); // default ctor and operator=

Why can't the compiler just write the new object into the existing object? I believe all instances of a class occupy the same amount of (non dynamic) memory, so I don't see why this would be a problem.

rmp251
  • 5,018
  • 4
  • 34
  • 46
  • Do you have optimizations turned on, are you using c++11 – aaronman Nov 27 '13 at 18:16
  • 5
    *Why can't the compiler just write the new object into the existing object?* ... and leak whatever resource `a` currently owns? – Praetorian Nov 27 '13 at 18:18
  • Some compilers might, if the constructor, assignment operator and destructor is compiler generated, or in some cases where those are trivial. –  Nov 27 '13 at 18:19
  • @aaronman Using c++03. – rmp251 Nov 27 '13 at 20:28
  • @Praetorian I guess I assumed the existing object would be properly destroyed first (but Sebastian's answer points out a flaw with that idea). – rmp251 Nov 27 '13 at 20:30

2 Answers2

6

RVO happens only because the C++ standard gives compilers a special license to ignore side effects in the copy constructor and the destructor of the temporary, which won't happen once the optimization is applied.

There is no such special license to ignore side effects in the assignment operator, so that can't be omitted. Furthermore, since a is valid before it is assigned to, it would first have to be destructed so that a new object can be constructed in place. Not only is there no special license to ignore side effects introduced by this destructor call, what's worse is that the destruction would have to happen before the function call, and then where would you be if the function throws?

Sebastian Redl
  • 69,373
  • 8
  • 123
  • 157
5

RVO works by constructing the returned value on the caller's stack frame.

In the first case, it can be constructed directly in the storage for a, since there is no object there yet.

In the second case, there is already an object there, so it will have to be constructed somewhere else before being assigned to a. You can't construct a new object on top of a, since that is not how assignment works.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • -1: The first case is not an assignment at all. What is checked for being callable (but will not be called) is the copy constructor, not the assignment operator. – 6502 Nov 27 '13 at 18:30
  • @6502 Why the -1? Mike doesn't say anything about the first case being assignment; if he doesn't explicitly say that it isn't, it's because it was clear from the question that it wasn't. – James Kanze Nov 27 '13 at 18:54
  • 3
    @6502: indeed, the first case isn't assignment, which is why I didn't say it was. – Mike Seymour Nov 27 '13 at 19:48
  • Mike, I was wondering *why* "you can't construct a new object on top of a," and *why* "that is not how assignment works." – rmp251 Nov 27 '13 at 20:34
  • Correct, I cannot remove the downvote unless the post is edited however (I'd classify this as a bug in SO). – 6502 Nov 27 '13 at 21:24