views:

981

answers:

4

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 ); 
}
+5  A: 

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.

anon
12.5 in my 1998 standard is "Free store" do you refer to some else standard?
Mykola Golubyev
Should have been 12.8/15
anon
+6  A: 

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"
Could you provide with the section number from the standard please?
Mykola Golubyev
The same that Neil posted: 12.15. Do you interpret it differently?
A: 

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.

RnR
it is not a good to shared_ptr std::string or std::pair or std::vector.
Mykola Golubyev
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.
xtofl
curious: why do you need this guarantee anyway xtof?
of course, the shared_pointer itself has a copy constructor
anon
@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.
RnR
@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 :).
xtofl
A: 

Way not pass parameter by reference and assign result to it?

Darius Kucinskas
because it's uglier and less flexible at the call site. it should be done only in performance-critical spots.
Or when you need multiple return values (a status and a value for instance)
xtofl