20

Possible Duplicate:
What are copy elision and return value optimization?

I am having difficulty understanding why in the following piece of code the copy constructor is not called.

#include <iostream>

class Test
{
public:
  Test(int){std::cout << "Test()" << std::endl;}
  Test(const Test&){std::cout << "Test(const Test&)" << std::endl;}
};

int main()
{
  // Test test;
  Test test2(Test(3));

  return 0;
}

Can someone explain why only the constructor is called and no copy constructor ?
Thanks.

Community
  • 1
  • 1
Adrian
  • 19,440
  • 34
  • 112
  • 219
  • 12
    Because compilers are awesome. Anyway, http://en.wikipedia.org/wiki/Copy_elision – chris Jan 04 '13 at 09:21
  • similar topic: http://en.wikipedia.org/wiki/Return_value_optimization – SS Hegde Jan 04 '13 at 09:28
  • I am glad that this question is still here in addition to the one with which it is marked as a duplicate. As someone who lacked familiarity with copy elision, it wasn't obvious to me that the other question covers the case shown here. – plafratt Sep 07 '18 at 18:16

3 Answers3

25

This is called as copy elision.
The compilers are allowed to do this optimization. Though it is not guaranteed by the standard any commercial compiler will perform this optimization whenever it can.


Standard Reference:

C++03 12.8.15:

[...] This elision of copy operations is permitted in the following circumstances (which may be combined to eliminate multiple copies):

[...]

  • when a temporary class object that has not been bound to a reference (12.2) would be copied to a class object with the same cv-unqualified type, the copy operation can be omitted by constructing the temporary object directly into the target of the omitted copy

You might use some compiler settings to disable this optimization, like in case of gcc, from the man page:

-fno-elide-constructor

The C++ standard allows an implementation to omit creating a temporary which is only used to initialize another object of the same type. Specifying this option disables that optimization, and forces G++ to call the copy constructor in all cases.

However, using this makes your code non portable across different compilers.

Alok Save
  • 202,538
  • 53
  • 430
  • 533
11

It is because of the optimization performed by your compiler. Compilers are permitted to perform such optimizations, though it is not a requirement, thus not guaranteed.

Note an important point that even though the copy-constructor is not invoked eventually, it is semantically required to be accessible. That is, if you make the copy-constructor private, your code will not compile!! It is because the semantic-check is done much before the optimization phase, means the compiler first checks that the copy-constructor is accessible or not; if it is accessible, then only comes the optimization phase where the copy-construction is elided.

Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • Another way of reasoning for the copy constructor to be accessible is that copy elision is not guaranteed. A compiler may or may not perform this optimization since standard does not mandate it. So if there exists a compiler which cannot perform this optimization then it needs the copy constructor to be accessible. So since standard does not enforce the optimization it cannot enforce the optimization to work without the copy constructor. – Alok Save Jan 04 '13 at 09:35
  • @AlokSave: Thanks. added few more words. – Nawaz Jan 04 '13 at 09:36
0

As others have already well mentioned this is because of optimization from your compiler.

I haven't checked it but you could probably compile your code with optimization and again without and have a look at the assembler code. Then you should also definetely see some differences.

Stefan
  • 2,603
  • 2
  • 33
  • 62