0

Consider the following:

class Foo { ... };

Foo rbv();

void caller()
{
  Foo x = rbv(); ← the return-value of rbv() goes into x
  ...
}

Foo rbv()
{
  ...
  return Foo(42, 73); ← suppose Foo has a ctor Foo::Foo(int a, int b)
}

How many objects of type Foo will be constructed?

Eduard Rostomyan
  • 7,050
  • 2
  • 37
  • 76

2 Answers2

3

Maybe.

In C++11, values are returned by moving, rather than copying, if they have a move constructor. This can be much more efficient than copying.

In some circumstances - such as when returning a local variable or a temporary (as you do here) - the move or copy can be elided. The value is created directly into the caller's stack frame, so that it doesn't need to be moved or copied on return. People who like acronyms sometimes call this (N)RVO - (Named) Return Value Optimisation.

Likewise, the copy or move from the temporary return value to x can also be elided.

Any decent compiler will implement this optimisation, so your code should only create a single Foo. You can verify this by making the destructor print a message, and observing that it only does this once: http://ideone.com/xydJqY. If you disable the optimisation, there may be up to three objects.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
1

There may be up to two copies: One from the temporary Foo(42, 73) to the return value of the function, and another from the return value of the function to x. However, both of those copies are eligible for copy elision, which allows for not making copies and instead constructing the object directly in the destination, equivalent to Foo x(42, 73);.

You may be able to control the extent to which your compiler takes advantage of copy elision; for example, in GCC you can use -fno-elide-constructors to get all two copies.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084