8

In the book Generic Programming and the STL (Chinese edition), it says:

X x = X() will call the copy constructor.

It seems a little weird to me. And I write a test program like this

#include <iostream>

class Test {

public:

    Test() {
        std::cout << "This is ctor\n";
    }

    Test(const Test&) {
        std::cout << "This is copy-ctor\n";
    }

};

int main(int argc, char** argv)
{

    Test t = Test();
    return 0;
}

The output is "This is ctor". ok, now I'm confused, which is right?

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
Xiaotian Pei
  • 3,210
  • 21
  • 40

3 Answers3

9

Nomimally yes, a temporary is default-constructed, and then the copy constructor is invoked to copy it into your object t.

However, in practice the copy can be optimised out — even though it has side effects (the console output):

[n3290: 8.5/16]: [..] In certain cases, an implementation is permitted to eliminate the copying inherent in this direct-initialization by constructing the intermediate result directly into the object being initialized; see 12.2, 12.8.

And (in conjunction with the example given in the same clause):

[n3290: 12.2/2]: [..] An implementation might use a temporary in which to construct X(2) before passing it to f() using X’s copy constructor; alternatively, X(2) might be constructed in the space used to hold the argument. [..]

But the copy constructor does still have to exist, even though it might not be invoked.

Anyway, if you compile with optimisations turned off (or, with GCC, possibly -fno-elide-constructors), you will see:

This is ctor
This is copy-ctor
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • 2
    In gcc, you may have to use `-fno-elide-constructors`, since even `-O0` doesn't prevent elision, I think. – Kerrek SB Aug 25 '11 at 12:09
  • The copy can be elided even when it is not *trivial*, the copy is elided by constructing the temporary in place of the local variable. The complexity of the object or the copy is irrelevant to that optimization. – David Rodríguez - dribeas Aug 25 '11 at 12:14
  • @Tomalak: Credits (and +50) to Steve Jessop for [discovering that option](http://stackoverflow.com/questions/6364365/can-different-optimization-levels-lead-to-functionally-different-code) :-) – Kerrek SB Aug 25 '11 at 12:16
  • Now wait. Weren't you the one who was so pissed-off the other day about those who start out their answer with just two sentences and then expand on that incrementally? `:)` – sbi Aug 25 '11 at 13:08
  • @sbi: Ah, but my answer was correct even in its most minimal form. IIRC the other day I was irritated by an answer that started off life as, basically, "answer coming soon..." – Lightness Races in Orbit Aug 25 '11 at 13:12
  • @sbi: More likely we are referring to distinct instances. :) – Lightness Races in Orbit Aug 25 '11 at 13:16
  • @Tomalak: Well, I am referring to the one I was referrin when I asked this question. `:)` – sbi Aug 25 '11 at 18:32
  • @sbi: Evidently I'm remembering a different one! – Lightness Races in Orbit Aug 25 '11 at 23:26
4

In theory, X x = X() will call the default constructor to create a temporary object, and copy that into x using the copy constructor.

In practice, compilers are allowed to skip the copy construction part and default-construct x directly (which, as David points out in his comment, still requires the copy constructor to be syntactically accessible, though). Most compilers do that at least when optimizations are enabled.

sbi
  • 219,715
  • 46
  • 258
  • 445
  • 4
    It is important to note that the copy constructor must be available, even if the copy is elided. That is, if it is not accessible the compiler will reject the line with an error. – David Rodríguez - dribeas Aug 25 '11 at 12:12
  • @David: You're right. I've incorporated that into my answer. Thanks for bringing this up. – sbi Aug 25 '11 at 13:13
2

This is a case where a form of Return Value Optimisation(RVO) (Also known as Copy Elision) can help out a lot on optimisation. The wikipedia page linked has a very good explanation of what is going on.

Goz
  • 61,365
  • 24
  • 124
  • 204