12

I am reading the official CPPCoreGuidelines to understand correctly when it's reliable to count on RVO and when not. At F20 it is written:

If a type is expensive to move (e.g., array), consider allocating it on the free store and return a handle (e.g., unique_ptr), or passing it in a reference to non-const target object to fill (to be used as an out-parameter)

I understand that the non-STL types are not optimized to move, but how can I easy detect other types expensive to move, so I will not use RVO on them?

Trevor Hickey
  • 36,288
  • 32
  • 162
  • 271
Taw
  • 479
  • 3
  • 15

1 Answers1

16

You seem to have misunderstood what "RVO" is. "RVO" stands for "return value optimization" and it's a compiler optimization that prevents any move or copy constructor from being invoked. E.g.

std::vector<huge_thing> foo()
{
    std::vector<huge_thing> result{/* ... */};
    return result;
}

void bar()
{
    auto v = foo(); // (0)
}

Any decent compiler will not execute any copy/move operation and simply construct v in place at (0). In C++17, this is mandatory thanks to the changes to prvalues.


In terms of expensive moves: sure, there can be types expensive to move - but I cannot think of any instance where a move would be more expensive than a copy.

Therefore:

  • Rely on RVO, especially in C++17 - this does not incur any cost even for types "expensive to move".

  • If a type is expensive to move, it's also expensive to copy - so you don't really have a choice there. Redesign your code so that you don't need the copy/move if possible.

Vittorio Romeo
  • 90,666
  • 33
  • 258
  • 416
  • 2
    Is F.20 actually a bad advice? It seems that they don't consider RVO here. They say "Bad: large value" for `Package fill();`, but because of RVO, it is not bad at all... – geza Nov 12 '17 at 14:15
  • I've understood what RVO is, I just did not express myself very clear in the question (english is not my native language). Perhaps I should have said "when I can trust my compiler that it will use RVO". At F20 example it seems that a copy is not necessary in the function, so why "rely" on RVO, when I can return it as a function reference? – Taw Nov 12 '17 at 20:01
  • So in F.20 Bjarne/Herb express very clear to not return a copy everytime and you say the opposite, just to rely on RVO everytime...I am a bit confused, sorry :) – Taw Nov 12 '17 at 20:11
  • @Taw - No they say don't return **arrays** of expensive objects. That's a specific advice, not a general "don't *return* things". – Bo Persson Nov 12 '17 at 22:01