Solved

Copy constructor - query

Posted on 2004-10-09
15
245 Views
Last Modified: 2010-04-01
Ah hello.

I feel a bit ashamed to ask this, since the answer is probably straight forward, but I guess this is one of those intricate little gems that you never consider until you have to...

I was taking some code apart involving copy constructors as follows:

class A
{
// other stuff

      static A Test() {  
            A a(10);
            return a;
      }
};

int main()
{
      A b = A::Test();
      return 0;
}

Now this is all incredibly simple stuff, but what I cannot see why is why the copy constructor is not called twice in this code (assume all functions have been added with appropriate 'cout' statements to show what is being called).  The way I see it is that the copy constructor first gets called when calling

return a;

since this is returning by value hence a copy is needed.  Now I figured that in the call of

b = A::Test()

which involves not the assignment operator but the copy constructor (since it is initialisation not assignment) we would call the copy constructor *again* to initialise 'b'.  *But this does not happen !*  And I know that 'b' is exactly the same as the object returned too.  I get exactly the same behaviour as if I just call

A::Test()

without using the return value.

Can someone please enlighten me ?

TIA
0
Comment
Question by:mrwad99
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 5
  • 4
15 Comments
 
LVL 15

Expert Comment

by:efn
ID: 12267365
I think the answer is simply that the compiler is allowed to optimize away temporary objects.  In fact, if you changed Test to do this:

return A(10);

you might not see the copy constructor called at all.  The compiler could just construct the object in b's space.

References:

http://cpptips.hyperformix.com/cpptips/ret_val_opt

http://groups.google.com/groups?hl=en&lr=&selm=76u9oe%24gor%241%40brokaw.wa.com&rnum=2
0
 
LVL 17

Expert Comment

by:rstaveley
ID: 12267367
You'll find that most compilers do return value optimisation.
0
 
LVL 19

Author Comment

by:mrwad99
ID: 12267393
Yeah that is right; there is no copy constructor being called when I just state

return A(10);

Now then, the crucial question remains, *was I correct in thinking that the copy constuctor should (in theory - putting all fancy optimisation aside) be called twice, most notably for the construction of b* ?
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 17

Expert Comment

by:rstaveley
ID: 12267419
Should? No. Legitimately could be... yes.
0
 
LVL 17

Expert Comment

by:rstaveley
ID: 12267425
If your compiler doesn't do return value optimisation, though, you ought to consider a different vendor.
0
 
LVL 19

Author Comment

by:mrwad99
ID: 12267442
Heh, it does support optimisation(VC++ 6.0) that is why I was not getting what I thought should be the required behaviour.

>> Should? No.

Why should it not ?

A b = A::Test();

is constructing an object by initialisation, not assignment, hence the copy constructor is being used.

return a;

is returning an object by value, so again the copy constructor is being called.

That makes two calls to the copy constructor.

If I am wrong correct me please, as I like to take things apart and hate being unsure of something.  But I am sure my reasoning is correct.
0
 
LVL 15

Accepted Solution

by:
efn earned 75 total points
ID: 12267671
Initialization does not always require a copy constructor call.  Section 12.8, clause 15 of the 2003 C++ standard ISO/IEC 14882 says:

"When certain criteria are met, an implementation is allowed to omit the copy construction of a class object, even if the copy constructor and/or destructor for the object have side effects.

...

This elision of copy operations is permitted in the following circumstances (which may be combined to eliminate multiple copies):

-- in a return statement in a function with a class return type, when the expression is the name of a non-volatile automatic object with the same cv-unqualified type as the function return type, the copy operation can be omitted by constructing the automatic object directly into the function’s return value

..."
0
 
LVL 17

Expert Comment

by:rstaveley
ID: 12267814
Actually...

     static A Test() {  
          A a(10);
          return a;
     }

... a is not an automatic object, so you'd expect a ctor for A and a ctor for b, but not the return value temporary object. Oddly enough this cropped up in another current thread to which you can see a simple little experiment I put together a few minutes ago. See http:/Q_21162108.html#12267755

[ BTW... I love the use of the word "elision" in the standard :-) ]
0
 
LVL 15

Expert Comment

by:efn
ID: 12268002
rs> a is not an automatic object

Why do you think that?  It looks pretty automatic to me:  local scope, not static, not extern.
0
 
LVL 17

Expert Comment

by:rstaveley
ID: 12268362
You're right efn it is an automatic object. I'm forgetting my basics.

I've got a vague confused memory of there being a difference between a named variable and a temporary object in the context of optimisation, which is illustrated by http:/Q_21162108.html#12267755 (my addled brain had automatic=unnamed i.e. temporary, which it isn't) ... but it is late on a Saturday night and I don't think I'm in the right frame of mind to wade through the C++ standard %-)
0
 
LVL 19

Author Comment

by:mrwad99
ID: 12271532
>> return A(10);

>> you might not see the copy constructor called at all.  The compiler could just construct the object in b's space.

So that means that there is no explicit call to any constructor of any kind; it is as if the temporary returned 'becomes' b just like that ?
0
 
LVL 15

Expert Comment

by:efn
ID: 12271931
> So that means that there is no explicit call to any constructor of any kind; it is as if the temporary returned 'becomes' b just like that ?

No, the A::A(int) constructor would be used to construct b.  Just the copy would be avoided.
0
 
LVL 19

Author Comment

by:mrwad99
ID: 12271968
Yeah, but what I meant was that there will only be only be *one* call to the constructor; effectively the object returned in

return A(10)

*is* b

due to compiler optimisation ?
0
 
LVL 17

Assisted Solution

by:rstaveley
rstaveley earned 25 total points
ID: 12272059
Yes
0
 
LVL 19

Author Comment

by:mrwad99
ID: 12272128
Many thanks both !
0

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Find Visual Studio Tools 2 135
How do i run a c++ file? 15 58
C++ help/ Toy problem 19 71
How do I get Window Title of all opened process? 4 61
Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

739 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question