How can I make sure the routine uses (N) RVO?

I would like to make sure my routines use (N) RVO whenever possible. With the exception of parsing as a result of a disassembly, is there anything I can do or check if the routine is compiled with (N) RVO? At the moment, I am most interested in MSVC and GCC.

+4
source share
3 answers

No, not at all.

However, when writing code, you can follow the guidelines.


Lossless return value optimization

This works a lot every time you return a temporary one, even in debug mode.

return MyObject(....); 

Name optimization

This almost works every time a function always returns the same temporary object:

 MyObject func() { MyObject result; if (...) { return result; } result.push(0); return result; } 

You can mix them, but the compiler can hardly use RVO in this case:

 MyObject func() { MyObject result; if (...) { return MyObject(...); } return result; } 

Here, probably, one return will be beneficial from the RVO, and the other not. And I would bet that the first one is optimized because you are stuck if you speculatively create result in the reverse slot and suddenly you need to take the if branch. Note that simply reordering the statements just works:

 MyObject func() { if (...) { return MyObject(...); } MyObject result; return result; } 

So, the rule of thumb for NRVO is that there should be no return between the result declaration and the return result; that returns anything else but result .


If you follow this, you add up the odds in your favor. And then it's just a matter of code review.

And you also make it easier to read code, since you do not declare variables before you know that you really need them.

+6
source

You can add debugging methods to the destructor:

 struct A { ~A() { cout << "destructor called"; } }; A foo() { A a; return a; } 

If the destructor is invoked, RVO is probably not applied.

+2
source

Possible ways that I can think of:

  • Implementing a link counting mechanism in your class that keeps track of the number of instances created using the class does something similar to shared_ptr , so you can detect additional copies of the created class and be deleted if copying does not occur.

  • You could just put the debug traces in the constructor and copy destructor for your class, if copying does not happen, you will see many sequential copy and debug trace constructors.

+1
source

Source: https://habr.com/ru/post/1400425/


All Articles