Issue
I'd like to make sure my routines are leveraging (N)RVO whenever possible. Other than parsing through the resulting disassembly, is there something I can do or check to see if a routine is being compiled with (N)RVO? At this point I'm mostly interested in MSVC and GCC.
Solution
No, not really.
However you can follow guidelines when writing your code.
Unnamed Return Value Optimization
This is pretty much triggered every time you return a temporary, even in Debug mode.
return MyObject(....);
Named Return Value Optimization
This is pretty much triggered every time the function always return the same local variable:
MyObject func() {
MyObject result;
if (...) { return result; }
result.push(0);
return result;
}
You can mix those, but it becomes nigh impossible for the compiler to apply RVO in this case:
MyObject func() {
MyObject result;
if (...) { return MyObject(...); }
return result;
}
Here, it is probably that one return will benefit from RVO and the other will not. And I would bet on the first being optimized because you'd be stuck if you speculatively create result
in the return slot and suddenly need to take the if
branch. Note that simply reordering the statements just work:
MyObject func() {
if (...) { return MyObject(...); }
MyObject result;
return result;
}
So the rule of thumb for NRVO is that there should be no return
statement between the declaration of result
and the return result;
statement that return anything else than result
itself.
If you follow this, you stack the odds in your favor. And then it's just a matter of code review.
And you also make your code easier to read since you do not declare variables before knowing that you really need them!
Answered By - Matthieu M. Answer Checked By - David Marino (WPSolving Volunteer)