Reputation: 10539
Move semantics can be useful when the compiler cannot use RVO and NRVO. But in which case can't the compiler use these features?
Upvotes: 6
Views: 1438
Reputation: 70516
The answer is that it is compiler and situation dependent. E.g. control flow branching might confuse optimizers. Wikipedia give this example:
#include <string>
std::string f(bool cond = false) {
std::string first("first");
std::string second("second");
// the function may return one of two named objects
// depending on its argument. RVO might not be applied
return cond ? first : second;
}
int main() {
std::string result = f();
}
Upvotes: 5
Reputation: 145239
Well, it's not so much whether the compiler can use RVO, but whether it thereby can avoid a copy construction.
Consider:
struct Blah
{
int x;
Blah( int const _x ): x( _x ) { cout << "Hum de dum " << x << endl; }
};
Blah foo()
{
Blah const a( 1 );
if( fermatWasRight() ) { return Blah( 2 ); }
return a;
}
Getting the side effects (output from the constructor) right here, is at first glance pretty incompatible with constructing a
directy in storage provided by the caller. But if the compiler is smart enough then it can note that destroying this object is a null-operation. And more generally, for any particular situation, if the compiler is smart enough then maybe it can manage to avoid a copy operation no matter how sneakily we design the code.
I'm not sure of the formal though, but the above, with more payload in the object so that copying would be more expensive, is one case where move semantics can help, so that optimization will be guaranteed no matter the smarts of the compiler (or not).
Upvotes: 3