Copy constructors and temporary object generation

According to this wikipedia entry: http://en.wikipedia.org/wiki/Copy_constructor

X a = X();

Should invoke the default constructor for X - creating a temp and then the copy constructor is called to initialize variable a (if I am reading this article correctly).

But from a little test app I wrote and compiled under g++ 4.4 only the default constructor is called (see below).

On a related note, is there any difference between the initialization of x1 and x2 in the following example.

class X { };
X x0;
X x1 = x0;
X x2 = X(x0);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// test app ------------------------------------------------
#include <iostream>

using namespace std;

class X {
    public:
        X(const X& x) {
            cout << "Copy constructor called." << endl;
        }

        X(int x) {
            cout << "Constructor called with " << x << "." << endl;
        }

        X() {
            cout << "Default constructor called." << endl;
        }


};


int main() {

    X x1 = X(); // only the default constructor is called

    return 0;
}



Last edited on
I have never tested, but I think X a = X() should have used the default constructor to create an object of type X (not stored in any variable) and it should have then used the copy constructor to build the object of type X that is stored in the variable 'a'. But you say your test proved this wrong. Interesting. Could it be a compiler optimization? I say try this in other compilers if possible.

There is no difference between the initializations of x1 and x2.

EDIT: Just a small note: There is no difference in your compiler that seems to take a shortcut when using constructors in the right hand side. I think, however, that theory states that there should be a difference.

x2 would be created using the same constructor as x1 (the copy constructor), but the source object for x2 would have been a copy of x0 and not x0 itself, as it has been passed to a call to the copy constructor. Hopefully I made sense.
Last edited on
A clever compiler (writer) would probably see
that X x1 = X(); is just a simple constructor call for x1 - (same as X x1()) and optimize away redundant copy construction and assignment calls.
Last edited on
+1 guestgulkan.

There is no difference.

These generate the same code:
1
2
X x;
X x = X();


These generate the same code -- all a single call to the copy constructor:
1
2
3
X x = X( other_x );
X x = other_x;
X x( other_x );' 


Thank you to everyone who replied.

I used an online c++ compiler (http://codepad.org) to compile the above code.

And the output I got was:

Output:
Default constructor called.
Copy constructor called.

Which probably means that the g++ compiler was optimizing the code, as many of you pointed out.

-----------------------

I also noticed a difference between initializing x1 and x2 with the online compiler

1
2
3
4
X x0;   // default constructor

X x1 = x0;        
X x2 = X(x0);


x1 - leads to a single copy constructor call
x2 - leads to two copy constructor calls - assuming one to create a temp and the second to initialize x2 with that temp.


------------------------------

And for those who are wondering, the online compiler is setup as:

C++: g++ 4.1.2

flags: -O -std=c++98 -pedantic-errors -Wfatal-errors -Werror -Wall -Wextra -Wno-missing-field-initializers -Wwrite-strings -Wno-deprecated -Wno-unused -Wno-non-virtual-dtor -Wno-variadic-macros -fmessage-length=0 -ftemplate-depth-128 -fno-merge-constants -fno-nonansi-builtins -fno-gnu-keywords -fno-elide-constructors -fstrict-aliasing -fstack-protector-all -Winvalid-pch


http://codepad.org/about

With -fno-elide-constructors being the option of interest. This option is supposed to be the default behavior of any c++ compiler according to the ANSI standard (g++ man-page), but this doesn't seem to be the case with g++.


Last edited on
Topic archived. No new replies allowed.