1

Possible Duplicate:
Why copy constructor is not called in this case?

Considering the following code snippet:

#include <iostream>

using namespace std;

class Test
{
        char name[16];
        public:
        Test ()
        {
                cout <<"Inside Constructor"<<endl;
        }

        Test (const Test & t)
        {
                cout <<"Inside Copy Constructor "<<endl;
        }

};

Test f()
{
        return Test();
}

int main ( int argc, char ** argv)
{
        Test t;
        Test t1 = f();

}

Test t1= f() -> it invokes f(), and which returns the Test object, and then as per my understanding the copy constructor should be invoked. But i get the following output:

Inside Constructor
Inside Constructor

what is wrong with my understanding?.

Community
  • 1
  • 1
Whoami
  • 13,930
  • 19
  • 84
  • 140

4 Answers4

2

Two copy elisions occur here.

The first is a kind of return value optimization (instead of copying the result of the expression Test() to the temporary object that is the return value of f, the expression Test() is evaluated by constructing directly into the temporary object that is the return value of f).

The second is the elision of the copy from the initializer expression of t1 to t1 itself (so instead of copying the temporary that is the return value of f into t1, the temporary that is the return value of f is constructed directly into t1).

The two elisions chain together -- so the memory of t1 is used as the destination when constructing the return value of f, and the memory for the return value of f is used as the destination when constructing Test(). So in effect t1 is direct-initialized by the no-args constructor and there are no copies needed.

Copy constructor elision is defined in the standard in 12.8/15 of C++03 and 12.8/31 of C++11 (which also allows elision of moves). It requires specific permission because it changes the observable behavior of the program (in your case it omits the side-effect of the copy constructor, the output). So it can only be performed under the conditions defined in the standard.

Both of these elisions are examples of the second permitted elision in C++03 (third in C++11), when the source is a temporary.

The first permitted elision is often called the "named return value optimization", and it allows a particular kind of copy to be omitted when the source is not a temporary.

Steve Jessop
  • 273,490
  • 39
  • 460
  • 699
1

Because return value optimisation removes the extra copy required.

GazTheDestroyer
  • 20,722
  • 9
  • 70
  • 103
1

It's called return value optimization.

detunized
  • 15,059
  • 3
  • 48
  • 64
0

Well I think you never call a copy constructor. You call a default constructor, get a temporary copy, and then an assignment operator is called.

EDIT. OK I missread Test t1 = f();. The RVO is indeed most probably kicking in f(). So its essentially equal to Test t1 = Test();.

I think this is one a few optimizations that is allowed be applied even if it can lead to change behaviour of the program. If you mangle with optimization flags you probably can get it to execute a copy constructor (+destructor on the old object).

luk32
  • 15,812
  • 38
  • 62