blackghost
blackghost

Reputation: 1825

c++ Return Value Optization

I am hoping someone can shed some light on what RVO does in g++. I have some third party software that I need to modify, and I'd like to optimize it as best possible, but I'm having trouble figuring out what exactly RVO does, and when it kicks in. My current structure looks something like:

class Foo {
private:
    Bar     myBar;
public:
    Bar &getBar() { return myBar; };
};

Where callers typically use it as so:

int x = foo.getBar().getX();

Because the return is a reference, there is no copy of the structure required, which is nice for performance reasons.

I need to modify Foo to use Bar2 instead of Bar for its internal structure, but, I need to keep the getBar() interface available for the third party callers. I have a function convertBar2ToBar(const struct Bar2 &bar2, struct Bar &bar), which can efficiently convert between the two structure types, but I'm concerned, as if I do:

Bar& Foo::getBar() { Bar rt; convertBar2ToBar(myBar2, rt); return rt }

Then this returns a reference to a variable on the stack, which can be scribbled on. I can alternatively modify the program to return a copy of rt as so:

Bar Foo::getBar() { Bar rt; convertBar2ToBar(myBar2, rt); return rt }

But now I'm worried that my Foo.getBar().getX() will be slow because it has to convert of Bar2 to rt (unavoidable), and then do a copy 'rt' to a local context of the caller (avoidable???)... I'm not clear whether RVO can prevent the copy, and if so, what exactly is going on under the hood.

Upvotes: 0

Views: 107

Answers (1)

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385144

I'm not clear whether RVO can prevent the copy

Yes, that is its purpose.

Furthermore, it's required to prevent the copy as of C++17.
(sorry no, it's not; that's for returning a prvalue; still, you can rely on NRVO in reality)

And if the copy is expensive enough to care about any of this in the first place, then it probably also ought to be movable in which case we again do not care about the cost.

and if so, what exactly is going on under the hood.

It doesn't matter.

But, on your 2017 PC, roughly speaking, rt will be "created" in the caller's stack frame rather than locally here. Thus, no copy required at all.

(And, indeed, don't return a reference to a local variable.)

Upvotes: 2

Related Questions