Destructor called twice with Return Value Optimization

128 Views Asked by At

In order to understand copy elision I wrote a small example

#include "iostream"

using namespace std;

struct Foo
{
    Foo() { cout << "constructor was called" << endl; }
    ~Foo() { cout << "destructor was called" << endl; }
};

Foo f()
{
    Foo foo;
    return foo;
}

int main()
{
    
    Foo bla = f();
    return 0;
}

output :

constructor was called
destructor was called
destructor was called

As I understand it, in the f() function the foo object is constructed directly in the memory space where bla is allocated so the constructor is called only once. I understand that when we exit the main() function, the bla object goes out of scope and the destructor is called. But why is the destructor called twice? Is the destructor of foo called when we exit the scope of the f() function even though the object is not destroyed and used by the caller?

1

There are 1 best solutions below

5
Karen Baghdasaryan On BEST ANSWER

I also added logging of copy constructor in the code, to illustrate what happens.

#include "iostream"

using namespace std;

struct Foo
{
    Foo() { cout << "constructor was called" << endl; }
    Foo(const Foo&) {cout << "copy constructor was called" << endl;}
    ~Foo() { cout << "destructor was called" << endl; }
};

Foo f()
{
    Foo foo;
    return foo;
}

int main()
{
    
    Foo bla = f();
    return 0;
}

The output is

constructor was called
copy constructor was called
destructor was called
destructor was called

So we see that from two possible object construction both took place, and one used copy-constructor.

If we turn on optimizations, we get

constructor was called
destructor was called

Now the object is constructed once directly in memory space, and the destructor is called once. Here is a DEMO