Sign in to follow this  
Thetan

Return Value Opitmization

Recommended Posts

Different sources have told me different ways to hint to the compiler to use the RVO. I know there isnt a garuntee a compiler will implement the optimization no matter how you hint, but whats the best way?

Share this post


Link to post
Share on other sites
I would think just enabling optimizations on most compilers would generally do this. Some compilers might have explicit switches to enable or disable it.

Share this post


Link to post
Share on other sites
Quote:
Original post by JohnBolton
RVO:
    Foo Bar()
{
...
return Foo( x, y, z );
}
NRVO:
    Foo Bar()
{
Foo f( x, y, z );
...
return f;
}

So basically, if i absolutely need to create an object and populate via the algorithm of the function, there is no way to even hint the RVO?

Share this post


Link to post
Share on other sites
Quote:
Original post by Thetan
So basically, if i absolutely need to create an object and populate via the algorithm of the function, there is no way to even hint the RVO?

RVO requires that the function returns an unnamed object. That pretty much restricts you to the form in the first example. I'm not an expert here so I don't know the details. However, some compilers also feature named RVO (the second example). You will have to check with the specific compilers to see what kind of restrictions they place on it.

Share this post


Link to post
Share on other sites
Note that for the RVO to work you cant actually do anything in the return value except create the object, for example, the standard prevents the compiler from performing the optimization if you write something like this...
Foo Bar()
{
// ...
return Foo(x, y, z) + w;
}
Theres also some explanations of what most compilers are able to do in the documentation for boost.operators
Quote:
T operator+( const T& lhs, const T& rhs )
{
T nrv( lhs );
nrv += rhs;
return nrv;
}
Given this implementation, the compiler is allowed to remove the intermediate object. Sadly, not all compiler implement the NRVO, some even implement it in an incorrect way which makes it useless here. Without the NRVO, the NRVO-friendly code is no worse than the original code showed above, but there is another possible implementation, which has some very special properties:
T operator+( T lhs, const T& rhs )
{
return lhs += rhs;
}
The difference to the first implementation is that lhs is not taken as a constant reference used to create a copy; instead, lhs is a by-value parameter, thus it is already the copy needed. This allows another optimization (12.2/2) for some cases. Consider a + b + c where the result of a + b is not copied when used as lhs when adding c. This is more efficient than the original code, but not as efficient as a compiler using the NRVO. For most people, it is still preferable for compilers that don't implement the NRVO, but the operator+ now has a different function signature. Also, the number of objects created differs for (a + b ) + c and a + ( b + c ).

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this