Search code examples
c++destructorreturn-value-optimization

Destructor called twice with Return Value Optimization


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?


Solution

  • 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