copy constructor

S

solid

Hi, I'm using g++ version 3.4.2 and the following program behaves
strangly:
class A {
public:
A(bool b) : b_(b) {}
A(const A& a) { b_ = !a.b_; }
bool get() const { return b_; }
private:
bool b_;

};

#include <iostream>
using namespace std;
int main() {
A x = A(A(true));
cout << x.get() << endl;

}

It outputs 1 rather than 0, specifically the copy constructor is not
called. Changing
A x = A(A(true));
to
A y = A(true);
A z = A(y);
cout << z.get() << endl;
outputs 0.
WHY???
 
V

Victor Bazarov

solid said:
Hi, I'm using g++ version 3.4.2 and the following program behaves
strangly:
class A {
public:
A(bool b) : b_(b) {}
A(const A& a) { b_ = !a.b_; }
bool get() const { return b_; }
private:
bool b_;

};

#include <iostream>
using namespace std;
int main() {
A x = A(A(true));

What do you suppose should happen here?
cout << x.get() << endl;

}

It outputs 1 rather than 0, specifically the copy constructor is not
called. Changing
A x = A(A(true));
to
A y = A(true);
A z = A(y);
cout << z.get() << endl;
outputs 0.
WHY???

The compiler is allowed to forgo creation of a temporary when initialising
an object like

A a = A(whatever);

It is allowed to generate code _as_if_ you wrote

A a(whatever);

V
 
M

Mark P

Victor said:
What do you suppose should happen here?


The compiler is allowed to forgo creation of a temporary when initialising
an object like

A a = A(whatever);

It is allowed to generate code _as_if_ you wrote

A a(whatever);

V

That seems to be a different point than the focus of the OP's question.
Eliminating the temporary as you illustrate would change his statement to:

A x(A(true));

Unless the temporary A(true) is also elided, this would still invoke the
copy ctor, no?

Mark
 
V

Victor Bazarov

Mark said:
[..]
That seems to be a different point than the focus of the OP's question.

That would mean that your guess is better than mine.
Eliminating the temporary as you illustrate would change his statement to:

A x(A(true));

Unless the temporary A(true) is also elided, this would still invoke the
copy ctor, no?

Try

struct A {
int i;
A(int i) : i(i) {}
A(A const& a) : i(a.i) {}
};

int main() {
A x(A(A(A(A(A(A(A(A(1)))))))));
return x.i;
}

on different compilers and tell me what return code your program has. On
VC++ v8 EE it's 5. On VC++ v7.1 EA it's 3. On MIPSPro C++ v7.4 it's 9.
That means to me that with some implementations _some_ copies are elided
and some aren't (and differently in different versions of the "same"
compiler). It's up to the compiler to decide which temporaries to create.
(BTW, g++ v3.2.2 refuses to compile it for some reason)

The moral of the story is "do not rely on side effects of the copy c-tor
when temporaries are involved".

V
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,999
Messages
2,570,246
Members
46,841
Latest member
WilmerBelg

Latest Threads

Top