NRV and the copy constructor

NRV and the copy constructor

Post by sbhat » Sun, 03 Aug 2003 17:58:14



While reading about the NRV optimization I learnt that one criteria
for this to be enabled is if the class has either an explicit or an
implicit copy constructor defined.

In general for a class T such as

class T
{
private:
    int _x;
    int _y;

Quote:}

and a Non member friend fuction of the class T such as

T operator+(const T& a, const  T& b)
{
    T retval;

    // stuff

    return T;

Quote:}

If the class T has a copy constructor the NRV will be applied in the
non member function such as the above, transforming the above
nonmember function to something like (name mangling et all left out
for clairty):

void T operator+(T& _result, const T& a, const T& b)
{
     _result.T::T();  //default constructor. I assume one exists...

     _result._x = a._x + b._x;
     _result._y = a._y + b._y;

Quote:}

Now the question is NRV gets enabled if and only if the copy
constructor exists..However the NRV optimization as above never uses
the copy constructor !! So why the requirement for NRV  that
stipulates the existence of a copy constructor which it does not
use...It seems a bit contradictory to me in the sense it requires a
copy constructor but never uses it so the question is why require it
then !! I am sure there is a very good rationale for this  but I have
not been able to come up with this rationale..Would appreciate if
anyone could shed more light on this...

thanks

best regards

Sabu

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

 
 
 

NRV and the copy constructor

Post by Sebastian Molesk » Mon, 04 Aug 2003 05:04:09



Quote:> While reading about the NRV optimization I learnt that one criteria
> for this to be enabled is if the class has either an explicit or an
> implicit copy constructor defined.

My interpretation of the intent behind that rule is access check. Every struct
has a copy constructor either provided by the compiler or provided by the
developer. However, you can prevent copying by making the copy constructor
private. In such an instance, the compiler must flag an error even if through
return-value optimization it would never use the copy constructor.

sm

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

 
 
 

NRV and the copy constructor

Post by John Potte » Mon, 04 Aug 2003 07:17:33



Quote:> While reading about the NRV optimization I learnt that one criteria
> for this to be enabled is if the class has either an explicit or an
> implicit copy constructor defined.

Every class has either an implicit or explicit copy constructor
declared.  The only way to not have it defined is for a user
declared and not defined version.

Quote:> In general for a class T such as
> class T
> {
> private:
>     int _x;
>     int _y;
> }

This has an implicitely defined copy ctor.

Quote:> and a Non member friend fuction of the class T such as
> T operator+(const T& a, const  T& b)
> {
>     T retval;

>     // stuff

>     return T;

return retval;

Quote:> }

The usual way to write this is

   T retval(a);   // uses copy ctor
   retval += b;
   return retval; // uses copy ctor by definition

Quote:> If the class T has a copy constructor the NRV will be applied in the
> non member function such as the above, transforming the above
> nonmember function to something like (name mangling et all left out
> for clairty):
> void T operator+(T& _result, const T& a, const T& b)
> {
>      _result.T::T();  //default constructor. I assume one exists...
>      _result._x = a._x + b._x;
>      _result._y = a._y + b._y;

What "stuff" did you write that produces this?

Quote:> }
> Now the question is NRV gets enabled if and only if the copy
> constructor exists..However the NRV optimization as above never uses
> the copy constructor !! So why the requirement for NRV  that
> stipulates the existence of a copy constructor which it does not
> use...It seems a bit contradictory to me in the sense it requires a
> copy constructor but never uses it so the question is why require it
> then !! I am sure there is a very good rationale for this  but I have
> not been able to come up with this rationale..Would appreciate if
> anyone could shed more light on this...

First, return by value requires a copy ctor.  If one exists, the
implementation may decide to perform some optimization.  If not,
the code is ill-formed, diagnostic required.

I suspect that you have been reading things about cfront-2 where the
RVO (now called NRVO by most) was first introduced.  That
implementation enabled RVO by an unusual compiler switch being the
user defined copy ctor.  The assumption being that if the user did
not define a copy ctor, it was not worth optimizing out the use.  At
that time, things were not at all clear, and there was no implicit
copy ctor using recursive copies of members required.  Today, that
switch does not exist in any implementation that I have seen.

John

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

 
 
 

1. base class copy constructor called from compiler generated copy constructor

Hi,
    From a compiler generated copy constructor, the copy constructor
of the base class gets called. But if I define a copy constructor,
then the base class default constructor gets called.

    (My interpretation of the I.S.O. standard is that the default constructor
should be called in both cases.)

    As illustrated by the following code : (tested with Sun CC 5.0,
gcc 3.1 and MSVC++ cl.exe )

#include <iostream>
using namespace std;

class one {
        public:
                one() { cout << "one default ctor\n"; }
                one(const one &o) { cout << "one copy ctor\n"; }

class two : public one {
        public:
                two() { }
                two(const two &o) { cout << "two copy ctor\n"; }

class three : public one {

main()
{
        two o1;
        three o2;
        cout << "about to call copy ctors\n";
        two o3(o1);
        three o4(o2);

The output is:

one default ctor
one default ctor
about to call copy ctors
one default ctor
two copy ctor
one copy ctor

   Could someone please explain this behaviour or point out the relevant part
of the standard that explains this ?

Thanks,
-pradeep.

2. Office licensing question - easy

3. copy-constructor that looks like a copy-constructor

4. ISDN For PC?

5. base class copy constructor called from compiler generated copy constructor

6. Applied Engineering HD floppy

7. constructor vs. copy constructor

8. PRINTMASTER Problem SOLVED!!!

9. why does copy-constructor hide default constructor?

10. copy constructor copies vector

11. should copy constructor copy reservation?

12. How to copy vector in copy constructor and assignment operator?

13. copy constructor but no copy destructor?