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 ?
"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.