1

I'm not an expert of C++ and i'm looking to the fastest way to return a value from a function. For example, for passing a value as a function arguemnt the fastest way is a const reference:

void foo(const bar& parameter);

Is possible to do something like this with return value? If i return a reference, maybe with something like this:

bar& foo();

Could i have any issue at runtime since the variable referred no longer exist (because the function foo has ended). Thank you in advice and sorry for my bad english

WileTheCoyot
  • 513
  • 1
  • 5
  • 20

4 Answers4

4

I think the best and cleanest way is to count on compiler performing RVO copy elision. This is one of few exceptions when optimization can change observable behaviour, and is widely used in modern popular compilers.

Returning a reference might be not suitable, because you need to ensure the object exists after the return. This fine for a method returning a property of the class. But it is not so easy if the object is created withing the function.

Other than that, you could of course return a pointer. But then someone has to release the object, or you need to use some kind of smart pointer.

Regarding std::move it is not a good idea to blindly use it whenever you want a "fast return" and do not trust the compiler. See: When should std::move be used on a function return value?.

Reiterating IMO, the best way is to write code that allows (N)RVO and trust the compiler.

Community
  • 1
  • 1
luk32
  • 15,812
  • 38
  • 62
  • I'm not saying std::move should be used when returning the value, but that doesn't mean you're not using move semantics. Simply defining a move constructor for your object should result in it being used where appropriate (for return at least). – heinrichj Mar 13 '14 at 10:04
  • @heinrichj Yea sure, I didn't put any words into your mouth either, I just wanted to point out, that using the move semantics explicitly is not a good idea. It can look tempting at start. Also I think copy elision is faster than move anyways. It is better to design code to avoid using constructor at all, if you can't then move, copy only as last a resort as it is slowest. BTW When you return value with defined move constructor, it does not mean you use either =) if RVO is applicable it will be preferred over move I think. – luk32 Mar 13 '14 at 10:32
  • Thanks for that last addition, I didn't think of that :) – heinrichj Mar 13 '14 at 10:37
1

Indeed you will have issues there. You can only do it if the lifetime of the object returned is not limited to the scope of the function (for example, you can return a reference to an object member).

For small POD-objects returning by value is usually not problematic. For more complex objects, particularly with dynamic memory allocations, making use of C++11's move semantics is the best way. If your bar defines a move constructor and you return it by value, it will be used automatically (instead of the copy constructor) if you return an instance by value from your function.

Edit: I agree with all the other folks saying RVO is the best option when it works, but if "likely copy elision" isn't good enough (i.e. very expensive copies) you should implement a move constructor.

heinrichj
  • 562
  • 2
  • 5
  • In this case move semantics are mostly a formalization of (N)RVO which already existed in C++98. – Benjamin Bannier Mar 13 '14 at 09:45
  • @BenjaminBannier: IIRC the effectiveness of RVO depends a lot on the compiler and the way in which the result is returned (returning a temporary or returning a local variable, multiple returns...), whereas move semantics have predictable results. – heinrichj Mar 13 '14 at 10:05
1

Return by value and helping the compiler do an RVO would be best.

One way of "helping" to compiler to make sure the function returns always same declared instance (and never any other instance - when depending on any conditions along the way).

For isntance do

bar f() {
  bar revtal;
  ..
  return retval
}

But not

bar f() {
  bar retval1;
  bar retval2;
  if(somecondition)
     return retval1;
  else return
     retval2;

}
GabiMe
  • 18,105
  • 28
  • 76
  • 113
0

Yes, is possible return a reference, but take care of return a reference to a field of the object, not a local variable of the function.

And take care too that mantain the reference only during the life of the object.

Community
  • 1
  • 1
Narkha
  • 1,197
  • 2
  • 12
  • 30