DevX Home    Today's Headlines   Articles Archive   Tip Bank   Forums   

Results 1 to 8 of 8

Thread: Named Return value optimization

  1. #1
    Join Date
    Dec 2003
    Location
    India
    Posts
    61

    Named Return value optimization

    Hi,

    Does the compiler perform named return value optimization for a method only when Copy Constructor is available for the returning object??

    If so, why??

    Thanks,
    Suresh.

  2. #2
    Join Date
    Nov 2003
    Posts
    4,118
    First, allow me to explain what the NRVO is for the sake of those who haven't heard this term before. The NRVO is an optional optimization that the compiler can apply when a function returns an object by value. For example:
    Code:
    class C
    {
    private:
    
    //...
    string C::getname() const
    {
     return string ("foo");
    }
    };
    When getname is called like this:
    Code:
    C c;
    string thename=c.getname();
    The return statement causes a copy of myname to be constructed on the caller's stack. To accomplish this, string's copy constructor is invoked. Next, that temporary copy is used as the argument of the assignment opeator of thename, so you actually have two copy constructions taking place: one for the temporary unnamed copy, and then thename itself. Obviously, the temporary copy is then destroyed, so the overhead of returning an object by value is quite high. To minimize this overhead, C++ compilers rewrite the getname function and every place of all. Instead of
    Code:
    string C::getname() const;
    The prototype is silently rewritten as:
    Code:
    void C::getname(string &s) const;
    Next, the body of getname is changed to:
    Code:
    void C::getname(string  &s ) const
    
    {
     s= "foo";
     return;
    }
    Finally, the call to getname is rewritten as:
    Code:
    string thename;
    c.getname(thename);
    Now to your question. Under the hood, getname() doesn't get a fully constructed object of type string. Instead, it gets a raw memory block akin to char[sizeof(string)], on which the result is constructed. In other words, the caller contrains something like this:
    Code:
    char __s[sizeof(string)];//unintialized yet
    getname(__s);//getname invokes the constructor of string, initializing s
    Seemingly, you don't need a copy constructor here since the copy constructor isn't called. Only the explicit constructor that takes const char * is needed. However, because the NRVO is optional, some compilers, under certain condition, will not aply this optimization. Instead, they will create the redundant copies on the caller's stack and use the copy constructor to initialize thename. So, while technically the copy constructor isn't essential, it's required by the standard.
    Last edited by Danny; 11-07-2006 at 11:12 AM.
    Danny Kalev

  3. #3
    Join Date
    Dec 2003
    Location
    India
    Posts
    61
    Danny,

    Thanks for the explanation.

    This brings another question from me.

    "Why should we have a copy constructor?"

    Apart from conditions where a copy constructor is mandatory (or synthesized by the compiler) or making a class eligible for NRVO, is there any advantages the Copy Constructor have over bitwise copy semantics?

    Lets take the example you have given...

    Will there be a performance hit if we dont provide a copy constructor?

    Will there be a performance difference between having a Copy constructor (assume no NRVO) and not having copy constructor??

    Thanks,
    Suresh.

  4. #4
    Join Date
    Jan 2005
    Location
    UK
    Posts
    604
    Hi,
    you will need to create a copy constructor when you have raw pointers as members of your class. The synthesized copy constructor does only a flat copy of pointers and doesn't copy the objects they're pointing to. Another example is if a copied object needs to have a different initial state from the original one.
    Cheers,
    D
    DKyb
    -------------------------------
    Life is a short warm moment -
    Death is the long cold rest.
    Pink Floyd
    -------------------------------

  5. #5
    Join Date
    Nov 2003
    Posts
    4,118
    Suresh,

    A class/struct always has a copy constructor, except when the user explicitly declares it and doesn't define it. The copy constructor may be compiler generated,in that case, it performs memberwise copying. This is sufficient in most cases, but not when you have raw pointers, handles, etc. In that case, you need to define your copy constructor explicitly so that it knows how to deal with pointer members. So the NRVO can be aplied to C structs as well, since they also have an implicit copy constructor in C++. Only when your class declares a non-public copy ctor (and doesn't define it), is the NRVO blocked.

    Many C programmer are surprised to learn that C++ generates a copy constructor for every class, struct and union. However, this isn't such a big deal since even C allows you to copy structs using the = operator.
    Danny Kalev

  6. #6
    Join Date
    Dec 2003
    Location
    India
    Posts
    61
    Danny,

    Does the compiler synthesize a Copy Cosntructor to all the classes?

    Stanley.B.Lippmann in his book "Inside C++ Object Model" says this

    "Default constructors and copy constructors…are generated (by the compiler) where needed.Needed in this instance means when the class does not exhibit bitwise copy semantics."

    by Quoting Annotated Reference Manual.And he also explains 4 conditions where a Copy constructor is nontrivial and synthesized by the compiler.

    He also gave an example of a class where a default Copy constructor is not needed..

    // declaration exhibits bitwise copy semantics
    class Word {
    public:
    Word( const char* );
    ~Word() { delete [] str; }
    // ...
    private:
    int cnt;
    char *str;
    };

    a default copy constructor need not be synthesized, since the declaration exhibits bitwise copy semantics


    Please let me know your thoughts.

    Thanks,
    Suresh.

  7. #7
    Join Date
    Nov 2003
    Posts
    4,118
    The copy constructor is always declared by the compiler, unless the programmer has explicitly declared / defined a copy constructor. The compiler decalred copy ctor may remain unimplemented; in this case, it is said to be a trivial copy ctor. In this case, the class gets bitwise copy semantics which merely copy chunks of raw memory (very much like memcpy does). In any event, you can always do something like:
    Code:
    T t1;
    T t2(t1);
    The only case in which t t2(t1) will not compile is when the copy constructor is explicitly declared (by the programmer) as non-public.

    A member wise copy constructor is synthesized in two conditions: when the user hasn't declared it explicitly, and when the class needs it.
    Now the question is: when does the class really need a copy ctor?
    All classes that have virtual member functions (either directly or by means of inheriting them from a base class), classes that have embedded objects with a non-trivial copy constructor and classes that have base classes with a non-trivial copy constructor require a copy constructor. In other words, the copy ctor is viral: if any subobject (base or member object) has is it, then the class will have it, too. Classes that have virtual base classes also necessitate a copy constructor.
    To summarize,

    You can always copy two objects of the same class, so long as the copy ctor isn't explicitly declared as non-public.

    If the programmer doesn't explictly declare a copy ctor, the compiler will declare a public copy ctor for the class.

    If the class in question needs a copy ctor (i.e., the copy ctor isn't trivial), the compiler will also define (not just declare) a memberwise copy constructor.

    Otherwise, bitwise copy semenatics will apply.
    Last edited by Danny; 11-09-2006 at 07:49 AM.
    Danny Kalev

  8. #8
    Join Date
    Dec 2003
    Location
    India
    Posts
    61
    Thanks for your explanation Danny.

    Suresh.

Similar Threads

  1. Switch Statement..return problem
    By XanFox in forum Java
    Replies: 3
    Last Post: 04-14-2011, 09:03 PM
  2. Getting a GUI to run
    By Eric in forum Java
    Replies: 4
    Last Post: 04-14-2006, 09:09 AM
  3. Input string was not in a correct format
    By mdengler in forum ASP.NET
    Replies: 0
    Last Post: 11-26-2002, 03:32 PM
  4. Re: App Object (fixes)
    By Rob Teixeira in forum .NET
    Replies: 129
    Last Post: 06-06-2002, 05:23 AM
  5. Getting a GUI to function
    By Eric in forum Java
    Replies: 1
    Last Post: 11-27-2001, 07:53 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center
 
 
FAQ
Latest Articles
Java
.NET
XML
Database
Enterprise
Questions? Contact us.
C++
Web Development
Wireless
Latest Tips
Open Source


   Development Centers

   -- Android Development Center
   -- Cloud Development Project Center
   -- HTML5 Development Center
   -- Windows Mobile Development Center