Monday, April 25, 2011

Copy constructor vs. return value optimization

In a previous question, it appeared that a plain return-by-value function always copies its return argument into the variable being assigned from it.

Is this required by the standard, or can the function be optimized by constructing the 'assigned to' variable even within the function body?

struct C { int i; double d; };

C f( int i, int d ) {
    return C(i,d); // construct _and_ copy-construct?
}

int main() {
    C c = f( 1, 2 ); 
}
From stackoverflow
  • The standard says that the copy constructor need not be used - see section 12.8/15:

    15 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.

    And much more in a similar vein.

    Mykola Golubyev : 12.5 in my 1998 standard is "Free store" do you refer to some else standard?
    anon : Should have been 12.8/15
  • The standard allows any level of copy omission here:

    • construct a local temporary, copy-construct it into a return value, and copy-construct the return value into the local "c". OR
    • construct a local temporary, and copy-construct that into "c". OR
    • construct "c" with the arguments "i,d"
    Mykola Golubyev : Could you provide with the section number from the standard please?
  • There's one very simple and good way to avoid such considerations completely - you can consider returning a boost::shared_ptr to the created object - it will be practically the same when it comes to usability but your object will surely not be copied unnecessarily - and it will be true also if you return it though a couple layers of function calls.

    Mykola Golubyev : it is not a good to shared_ptr std::string or std::pair or std::vector.
    xtofl : To avoid copy-construction, I could use heap i.s.o. stack storage. I know that :)/ But I wanted to know if I can trust the compiler i.e. the standard to _guarantee_ calling my copy constructor. Which I can't.
    anon : of course, the shared_pointer itself has a copy constructor
    RnR : @Mykola - why do you think it's not good? It's exactly this kind of return values that it may be very good to share_ptr the result and avoid a huge vector or a long string copied numerous times as you return it from some inner methods.
    xtofl : @Iraimbilanja: this question rose to me when the 'other' question's answers said the copy constructor would always be called on return. I doubted that. My question was a bit rhetorical, I must admit :).
  • Way not pass parameter by reference and assign result to it?

    xtofl : Or when you need multiple return values (a status and a value for instance)

0 comments:

Post a Comment