Hammad Ali
Hammad Ali

Reputation: 13

Where (in memory) does copy constructor copy the return value of function?

From what I've learned so far about C++, copy constructor is called in 3 situations

  1. When object is passed by value
  2. When a function returns an object.
  3. When object is declared and initialized with another object of same type.
#include "Cube.h"
using uiuc::Cube; 
Cube foo()
 {
  Cube c; 
 return c;    //copy constructor is invoked (BUT where is this copied value stored?)
}
int main()
 {
  Cube c2 = foo();  // copy constructor is invoked yet again !!! 
 return 0;
}

In the above code, copy constructor is invoked two times. First time for return c; and Second time for Cube c2 = foo(); I have three questions

  1. Where is returned object c copied to?
  2. Why does not the constructor directly store (copy) the returned object(i.e c) in c2 ? Would not it be more efficient?
  3. If the returned object c is not being stored in some variable like c2, why is the copy constructor still invoked?

Upvotes: 0

Views: 95

Answers (1)

HolyBlackCat
HolyBlackCat

Reputation: 96941

In the above code, copy constructor is invoked two times

If your type has a move constructor, it will be used instead of the copy constructor in this case.

In any case, here the move (or copy) constructor is called 0 or 1 times depending on compiler optimizations (could also be 2 times before C++17).

You start with 2 moves: first c is moved to a temporary object, then that temporary object is moved to c2.

The second move can be optimized away, this is called RVO. This optimization is mandatory starting with C++17.

The first move can be optimized away as well, but compilers are not required to do it. This is called NRVO.

When a move (or copy) is "optimized away", it's achieved by making the source and the destination the same object. So, e.g. if both RVO and NRVO happen, c and c2 become the same object.

Where is returned object c copied to?

Why does not the constructor directly store (copy) the returned object(i.e c) in c2 ?

If RVO and NRVO don't happen, it's moved to a temporary object.

If RVO happens, it's moved to c2.

If both RVO and NRVO happen, c2 and c are the same object, so no moves are needed.

Upvotes: 3

Related Questions