Understanding return value optimization and time series return - C ++

Please consider three functions.

std::string get_a_string() { return "hello"; } std::string get_a_string1() { return std::string("hello"); } std::string get_a_string2() { std::string str("hello"); return str; } 
  • Will RVO be applied in all three cases?
  • Is it possible to return a temporary value, as in the above code? I believe that this is normal, since I am returning it by value, and not returning a link to it.

Any thoughts?

+23
c ++ compiler-construction return-value-optimization
08 Sep '09 at 14:05
source share
4 answers

In the first two cases, RVO optimization will be carried out. RVO is an old feature, and most compilers support it. The latter case is called the so-called NRVO (Named RVO). This relatively new feature is C ++. The standard allows, but does not require, the implementation of NRVO (as well as RVO), but some compilers support it.

You can learn more about RVO in the 20th issue of Scott Meyers' book More Effective C ++. 35 New ways to improve your programs and designs .

Here 's a good article on NRVO in Visual C ++ 2005.

+16
Sep 08 '09 at 14:16
source share

First, it’s quite normal to return the temporary value that you are doing. It is copied, and although the original is beyond the scope, the copy will not do this and can be safely used by the caller.

Secondly, all three cases are actually identical (since in any case you do not have access to the temporary in the third case), and the compiler can even issue the same code for all of them. Therefore, he can use RVO in all three cases. It is entirely up to the compiler.

+7
Sep 08 '09 at 14:10
source share

All cases are correct. All of them will build a temporary one and apply the copy constructor of the return type. Mandatory, if there is no copy constructor, the code will not be executed.

RVO will occur in all three cases on most compilers. The only difference is the last when the standard does not force it. This is because you have a named variable. But most compilers are smart enough to apply RVO to it ... the later a named variable is declared, and the fewer conversions it applies, the more likely it is to apply RVO to a named variable.

By the way, returning the link is, of course, possible, as you could see in another code. What you should not do is return the link t to the local object.

 std::string& get_a_string2() { std::string str("hello"); return str; //error! } 

Will produce a compile-time error, as you know. However,

 std::string& get_a_string2(std::string& str) { // do something to str return str; //OK } 

Will work great. In this case, construction or copying is not provided. The function simply returns a reference to its argument.

+2
Sep 08 '09 at 14:21
source share
  • It depends on your compiler - which platform are you referencing? The best way to find out is to build a very small test application and check out the ASM that your compiler produces.

  • Yes, everything is fine, although you never mention what bothers you; speed? style? you can use a local temporary binding to a constant link - the lifetime of a temporary link will be extended to the life of the link - try it and see for yourself! (Herb Sutter exaplins this here ) See, for example, end of post.

IMO, you almost always trust your compiler better to optimize your code for you. There are very few cases where you need to take care of this (a very low level of code is one such area where you interact with hardware registers).

 int foo() { return 42; } int main(int, char**) { const int &iRef = foo(); // iRef is valid at this point too! } 
+1
Sep 08 '09 at 14:10
source share



All Articles