Search code examples
c++compiler-optimizationc++20rvo

When is RVO garanteed to apply / does apply with C++20 compilers


The C++ core guidelines states that

F.20: For “out” output values, prefer return values to output parameters

But then gives the following exception:

struct Package {      // exceptional case: expensive-to-move object
    char header[16];
    char load[2024 - 16];
};

Package fill();       // Bad: large return value
void fill(Package&);  // OK

Isn't it supposed to be a case where the return value optimization kicks in ? Is RVO prevented in this case ? Or still not as efficient as passing by reference ? Or is it that some compilers don't manage to do it ?

More generally, when should I rely on the compiler optimizing return values as efficiently as the pass-by-reference technique ?


Solution

  • "Plain" RVO (i.e., returning a prvalue or "temporary" in common parlance) is guaranteed in C++17 and well-supported even before that.

    NRVO (i.e., returning a local variable) can be finicky and is not guaranteed, and if it's not performed then you get a move instead. If your move is expensive, you may want to avoid that.

    In the example, there's a decent chance that fill needs to use the latter.