Can a return value be optimized out in case it is dependent in function parameter?

119 Views Asked by At

For the following code, I get in C++17:

move ctor
dtor
--------------------------------------------------------------------------------
dtor

Is this a possible output as well? i.e the move c'tor be elided and object be constructed in the caller side? Yes or No? And why?

--------------------------------------------------------------------------------
dtor

This is the code:

struct Foo {
    Foo() {}
    Foo(const Foo&) { std::cout << "copy ctor" << std::endl; }
    Foo(Foo&&) { std::cout << "move ctor" << std::endl; }
    ~Foo() { std::cout << "dtor" << std::endl; }
};

Foo passit(Foo f) {
    return f;
}

int main() {
    Foo f = passit(Foo{});
    std::cout << std::string(80, '-') << std::endl;
}
1

There are 1 best solutions below

2
wearetherobots On

https://en.cppreference.com/w/cpp/language/copy_elision

In a return statement, when the operand is the name of a non-volatile object with automatic storage duration, which isn't a function parameter or a catch clause parameter, and which is of the same class type (ignoring cv-qualification) as the function return type. This variant of copy elision is known as NRVO, "named return value optimization."

Furthermore, it's hard to see how the compiler could decide on this line that the Foo object should be constructed at the address of f, without knowing what happens within passit(), because this is effectively what would be required to optimise that copy out:

Foo f = passit(Foo{});