Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   Copy constructor doesn't get called when initialized by functionreturning object of same class (http://www.velocityreviews.com/forums/t619800-copy-constructor-doesnt-get-called-when-initialized-by-functionreturning-object-of-same-class.html)

abhash 06-12-2008 06:05 AM

Copy constructor doesn't get called when initialized by functionreturning object of same class
 
I am bit puzzled at the following piece of code I tried:

----------------------------------------------------------------------------------
#include <iostream>
using namespace std;

class Test {
public:
Test() { cout<<"Cons\n";}
Test(Test& a) { cout<<"Copy cons\n";}

};

Test fun()
{
return Test();

}

int main()
{
cout<<"First way of initialization\n";
Test t1;
Test t2 = t1;

cout<<"\nSecond way of initialization\n";
Test t3 = fun();
return 0;

}

OUTPUT (when compiled on CC compiler) :

First way of initialization
Cons
Copy cons

Second way of initialization
Cons
------------------------------------------------------------------------------------

I am intrigued why second initialization doesn't call copy
constructor ?
Aren't we passing the temporary object returned by fun() call to the
t3 for copying ?

Ian Collins 06-12-2008 08:01 AM

Re: Copy constructor doesn't get called when initialized by functionreturning object of same class
 
abhash wrote:
> I am bit puzzled at the following piece of code I tried:


> <snip>
>
> I am intrigued why second initialization doesn't call copy
> constructor ?
> Aren't we passing the temporary object returned by fun() call to the
> t3 for copying ?


Google for "C++ RVO"

--
Ian Collins.

sumsin 06-12-2008 08:13 AM

Re: Copy constructor doesn't get called when initialized by functionreturning object of same class
 
On Jun 12, 11:05 am, abhash <amit.abh...@gmail.com> wrote:
> I am bit puzzled at the following piece of code I tried:
>
> ----------------------------------------------------------------------------------
> #include <iostream>
> using namespace std;
>
> class Test {
> public:
> Test() { cout<<"Cons\n";}
> Test(Test& a) { cout<<"Copy cons\n";}


This is not the right syntax for copy constructor. It should be like:

Test(const Test& a)

>
> };
>
> Test fun()
> {
> return Test();
>
> }
>
> int main()
> {
> cout<<"First way of initialization\n";
> Test t1;
> Test t2 = t1;
>
> cout<<"\nSecond way of initialization\n";
> Test t3 = fun();
> return 0;
>
> }
>
> OUTPUT (when compiled on CC compiler) :
>
> First way of initialization
> Cons
> Copy cons
>
> Second way of initialization
> Cons
> ------------------------------------------------------------------------------------
>
> I am intrigued why second initialization doesn't call copy
> constructor ?
> Aren't we passing the temporary object returned by fun() call to the
> t3 for copying ?



Mirco Wahab 06-12-2008 09:08 AM

Re: Copy constructor doesn't get called when initialized by functionreturning object of same class
 
abhash wrote:
> I am bit puzzled at the following piece of code I tried:
> ...
> #include <iostream>
> using namespace std;
> [snipped]
> First way of initialization
> Cons
> Copy cons
>
> Second way of initialization
> Cons
> ...
> I am intrigued why second initialization doesn't call copy
> constructor ?
> Aren't we passing the temporary object returned by fun() call to the
> t3 for copying ?


Why should it? It's not initialized from an
instantiated object. This question (together
w/RVO) has been discussed frequently, eg.
here: http://forums.msdn.microsoft.com/en-...-fa083cdb94b3/

BTW, your code wouldn't compile on my gcc (4.3.1)
I had to modify it like:

...
class Test {
public:
Test() { cout<<"Cons\n";}
Test(const Test& a) { cout<<"Copy cons\n";}
};
...

so the /const/ was required to get disambiguation?
I'm not sure if this as required now so in the
standard, maybe the experts can say a word.

Regards

Mirco

abhash 06-12-2008 06:47 PM

Re: Copy constructor doesn't get called when initialized by functionreturning object of same class
 
On Jun 12, 1:01 pm, Ian Collins <ian-n...@hotmail.com> wrote:
> abhash wrote:
> > I am bit puzzled at the following piece of code I tried:
> > <snip>

>
> > I am intrigued why second initialization doesn't call copy
> > constructor ?
> > Aren't we passing the temporary object returned by fun() call to the
> > t3 for copying ?

>
> Google for "C++ RVO"
>
> --
> Ian Collins.


Thanks Ian for pointing to RVO term. Found quite a lucid explanation
for it here:

http://www.informit.com/guides/conte...lus&seqNum=199

-Amit

Roland Pibinger 06-12-2008 08:21 PM

Re: Copy constructor doesn't get called when initialized by function returning object of same class
 
On Thu, 12 Jun 2008 11:47:10 -0700 (PDT), abhash wrote:
>Thanks Ian for pointing to RVO term. Found quite a lucid explanation
>for it here:
>
>http://www.informit.com/guides/conte...lus&seqNum=199


RVO is a bug in the C++ language. Your copy constructor could contain
thousands of lines of code (code with side effects) which may be
blissfully elided by a compiler in the mood.



--
Roland Pibinger
"The best software is simple, elegant, and full of drama" - Grady Booch

James Kanze 06-13-2008 11:31 AM

Re: Copy constructor doesn't get called when initialized by functionreturning object of same class
 
On Jun 13, 4:11 am, Francis Litterio <em...@not.available> wrote:
> Roland Pibinger wrote:
> > On Thu, 12 Jun 2008 11:47:10 -0700 (PDT), abhash wrote:
> >>Thanks Ian for pointing to RVO term. Found quite a lucid explanation
> >>for it here:


> >>http://www.informit.com/guides/conte...lus&seqNum=199


> > RVO is a bug in the C++ language. Your copy constructor
> > could contain thousands of lines of code (code with side
> > effects) which may be blissfully elided by a compiler in the
> > mood.


> But since those "thousands of lines of code" should do nothing
> but than copy the internal state of the object, the object
> created by RVO should have state identical to what its state
> would be if your copy constructor had been invoked.


But that's not a requirement.

> Hence, the "O" (Optimization) in RVO.


The word "bug" isn't correct, because it is an intentional
compromise. RVO definitly violates the basic C++ object model.
On the other hand, it can make a significant difference in
performance with most compilers, AND it shouldn't make a
significant difference in the behavior of a well designed and
written program.

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient�e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S�mard, 78210 St.-Cyr-l'�cole, France, +33 (0)1 30 23 00 34

Daniel Pitts 06-14-2008 06:20 PM

Re: Copy constructor doesn't get called when initialized by functionreturning object of same class
 
James Kanze wrote:
> On Jun 13, 4:11 am, Francis Litterio <em...@not.available> wrote:
>> Roland Pibinger wrote:
>>> On Thu, 12 Jun 2008 11:47:10 -0700 (PDT), abhash wrote:
>>>> Thanks Ian for pointing to RVO term. Found quite a lucid explanation
>>>> for it here:

>
>>>> http://www.informit.com/guides/conte...lus&seqNum=199

>
>>> RVO is a bug in the C++ language. Your copy constructor
>>> could contain thousands of lines of code (code with side
>>> effects) which may be blissfully elided by a compiler in the
>>> mood.

>
>> But since those "thousands of lines of code" should do nothing
>> but than copy the internal state of the object, the object
>> created by RVO should have state identical to what its state
>> would be if your copy constructor had been invoked.

>
> But that's not a requirement.

Its not an enforced requirement, but neither is proper synchronization
in multi-threaded applications. You'll just be sorry if you don't follow
it, but the compiler will let you do whatever you want. Point gun at
foot and pull trigger.
>
>> Hence, the "O" (Optimization) in RVO.

>
> The word "bug" isn't correct, because it is an intentional
> compromise. RVO definitly violates the basic C++ object model.
> On the other hand, it can make a significant difference in
> performance with most compilers, AND it shouldn't make a
> significant difference in the behavior of a well designed and
> written program.

I'm not sure how to respond to this, I haven't been into the depths of
C++ development long enough to have an opinion on "basic C++ object
model", and "the behavior of a well designed and written program". I
think I agree with your second point, but I'm not sure that the basic
C++ object model is that well defined.

It does make me wonder if RVO has ever interacted poorly with RAII
though. Not sure they ever really meet, but if they did, I could see
anguish and surprise :-)

--
Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>

James Kanze 06-14-2008 10:53 PM

Re: Copy constructor doesn't get called when initialized by functionreturning object of same class
 
On Jun 14, 8:20 pm, Daniel Pitts
<newsgroup.spamfil...@virtualinfinity.net> wrote:
> James Kanze wrote:
> > On Jun 13, 4:11 am, Francis Litterio <em...@not.available> wrote:
> >> Roland Pibinger wrote:
> >>> On Thu, 12 Jun 2008 11:47:10 -0700 (PDT), abhash wrote:
> >>>> Thanks Ian for pointing to RVO term. Found quite a lucid explanation
> >>>> for it here:


> >>>>http://www.informit.com/guides/conte...lus&seqNum=199


> >>> RVO is a bug in the C++ language. Your copy constructor
> >>> could contain thousands of lines of code (code with side
> >>> effects) which may be blissfully elided by a compiler in the
> >>> mood.


> >> But since those "thousands of lines of code" should do nothing
> >> but than copy the internal state of the object, the object
> >> created by RVO should have state identical to what its state
> >> would be if your copy constructor had been invoked.


> > But that's not a requirement.


> Its not an enforced requirement, but neither is proper
> synchronization in multi-threaded applications. You'll just be
> sorry if you don't follow it, but the compiler will let you do
> whatever you want. Point gun at foot and pull trigger.


There's a difference. The lack of proper synchronization in
multi-threaded applications is undefined behavior. A copy
constructor which doesn't copy, or does more than just copy, is
more a style issue; it will confuse the maintenance programmers
to no end, but hey, that's their problem, not yours:-). There's
also the fact that "proper synchronization" is rigorously
defined, where as what exactly it means to copy may depend on
the application. (I have at least one case where a copy
constructor does modify the logical internal state of the copied
object.)

There's one other major difference, too: lack of proper
synchronization is more or less existing practice (which is one
reason why so many programs crash all the time), where as a copy
constructor which doesn't copy is really rare (in my experience,
and supposing the appropiate definition of "copy").

> >> Hence, the "O" (Optimization) in RVO.


> > The word "bug" isn't correct, because it is an intentional
> > compromise. RVO definitly violates the basic C++ object
> > model. On the other hand, it can make a significant
> > difference in performance with most compilers, AND it
> > shouldn't make a significant difference in the behavior of a
> > well designed and written program.

>
> I'm not sure how to respond to this, I haven't been into the
> depths of C++ development long enough to have an opinion on
> "basic C++ object model", and "the behavior of a well designed
> and written program". I think I agree with your second point,
> but I'm not sure that the basic C++ object model is that well
> defined.


It's very rigorously defined, the copy constructor is a
constructor, and while it can be provided by the compiler, it
has no other particular privileges nor, as far as the language
itself is concerned, responsibilities.

> It does make me wonder if RVO has ever interacted poorly with
> RAII though. Not sure they ever really meet, but if they did,
> I could see anguish and surprise :-)


Most of the time, of course, RAII classes don't support copy.
But there are exceptions, some of which (e.g. boost::shared_ptr)
are widely used. The standards committee very definitely
considered these, and if RVO does cause problems with them, it
should be considered a bug in the standard. (I think the way
RVO was originally specified did cause problems in some cases.
And the specification was modified so that it wouldn't.)

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique oriente objet/
Beratung in objektorientierter Datenverarbeitung
9 place Smard, 78210 St.-Cyr-l'cole, France, +33 (0)1 30 23 00 34


All times are GMT. The time now is 12:19 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.