By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,750 Members | 1,165 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,750 IT Pros & Developers. It's quick & easy.

A question about copy constructors in C++

P: n/a
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() ?
Jul 12 '06 #1
Share this Question
Share on Google+
2 Replies


P: n/a
flamexx7 wrote:
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.

--
Alan Johnson
Jul 12 '06 #2

P: n/a
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

Jul 12 '06 #3

This discussion thread is closed

Replies have been disabled for this discussion.