A question about copy constructors in C++

F

flamexx7

http://www.rafb.net/paste/results/V3TZeb28.html
In this code, why copy constructor is not called while returning object from
no_arg() . I was trying to find answer in C++ Standard. and there it's
written that

"Whenever a temporary class object is copied using a copy constructor, and
this object and the copy have the same cv-unqualified type, an
implementation is permitted to treat the original and the copy as two
different ways of referring to the same object and not perform a copy at
all, even if the class copy constructor or destructor have side effects"

I tried to changed object typeof y in function no_arg() to const, and still
copy constructor is not called. Can any one explain me, why does compiler
behaves to both objects differently while returning objects from no_arg()
and pass_arg() ?
 
A

Alan Johnson

flamexx7 said:
http://www.rafb.net/paste/results/V3TZeb28.html
In this code, why copy constructor is not called while returning object from
no_arg() . I was trying to find answer in C++ Standard. and there it's
written that

"Whenever a temporary class object is copied using a copy constructor, and
this object and the copy have the same cv-unqualified type, an
implementation is permitted to treat the original and the copy as two
different ways of referring to the same object and not perform a copy at
all, even if the class copy constructor or destructor have side effects"

I tried to changed object typeof y in function no_arg() to const, and still
copy constructor is not called. Can any one explain me, why does compiler
behaves to both objects differently while returning objects from no_arg()
and pass_arg() ?

The "cv-unqualified type" is the type you get if you ignore the const
and volatile qualifications. Even after you add const, both the source
and destination for every copy being made has a cv-unqualified type of
test_cc, so your compiler can (and apparently does) eliminate the copies.
 
P

petke

Hi, Here are my two cents worth..

One might think that if a function (without parameters) returns a
object by value, a) it would first have to create the local object, b)
then copy construction a return value (with longer lifetime). And c)
finally copy construct this object into the named object that is to
stores the result. That makes one construction and two copy
constructions.

test_cc no_arg(){
test_cc y("y"); // time a) a construction of local object
y.dostuff();
return y; // time b) a copy construction of unnamed temporary
}

main(){
test_cc ret_obj2 = no_arg(); // time c) a copy construction
}

I don't think any compilers actually do the last step. They combine
the b) and c) steps. The compiler knows what object will store the
result from the function, so this information can be passed to the
function as a hidden argument (by some compiler magic). That means the
function can create object ret_obj2 at the time off b) and thereby
remove one temporary.

This still leaves us with one construction and one copy construction.
Compilers using NRVO (Named return value optimization) can remove the
remaining copy construction. Since the compiler knows that object
ret_obj2 will be used to store the result, it can create this object at
time a) instead and thereby remove the remaining temporary. This leaves
us with only one construction.

So why does the second function involves more copy constructions.

test_cc pass_arg(test_cc arg) { // time a) a copy construction
arg.dostuff();
return arg; //time b) a copy construction
}

main(){
test_cc x("x"); // time a-1) a construction of object
test_cc ret_obj1 = pass_arg(x); //time c) a copy construction
}

Counting that gives me three copy constructions and one construction.
That is one more copy construction right there. Because the object at
time off a-1) is already created before the function is called, it
means the object is not a local temporary and the compiler can not
optimize it away. So this version should always have one copy
construction more than the first version. Other than that the same
optimizations should apply. So that leaves us with one construction and
one copy construction.

So that is what i think is going on, I hope it answered your question.

(Note: I could not test the NRVO optimizations since my compiler does
not support it.)

Regards Patrik
 

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

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,158
Latest member
Vinay_Kumar Nevatia
Top