Alex Rivera | Logout

g++: How RVO works in case that multiple translation units are involved

Asked 2012-07-23T15:05:44.780
10

Firstly please take a look at the following code, which consists of 2 translation units.

--- foo.h ---

class Foo
{
public:
    Foo();
    Foo(const Foo& rhs);
    void print() const;
private:
    std::string str_;
};

Foo getFoo();

--- foo.cpp ---
#include <iostream>

Foo::Foo() : str_("hello")
{
    std::cout << "Default Ctor" << std::endl;
}

Foo::Foo(const Foo& rhs) : str_(rhs.str_)
{
    std::cout << "Copy Ctor" << std::endl;
}

void Foo:print() const
{
    std::cout << "print [" << str_ << "]" << std:endl;
}

Foo getFoo()
{
    return Foo(); // Expecting RVO
}

--- main.cpp ---
#include "foo.h"

int main()
{
    Foo foo = getFoo();
    foo.print();
}

Please be sure that foo.cpp and main.cpp are different translation units. So as per my understanding, we can say that there is no implementation details of getFoo() available in the translation unit main.o (main.cpp).

However, if we compile and execute the above, I could not see the "Copy Ctor" string which indicates that RVO works here.

It would be really appreciated if anyone of you kindly let me know how this can be achieved even if the implementation details of 'getFoo()' is not exposed to the translation unit main.o?

I conducted the above experiment by using GCC (g++) 4.4.6.

Edit
Report

1 Answer

6

main doesn't need the implementation details of getFoo for RVO to occur. It simply expects the return value to be in some register after getFoo exits.

getFoo has two options for this - create an object in its scope and then copy (or move it) to the return register, or create the object directly in that register. Which is what happens.

It's not telling main to look anywhere else, nor does it need to. It just uses the return register directly.

answered 2012-07-23T15:19:00.383

Your Answer