Search code examples
c++returnmingwcl

return object created in function. mingw and cl difference


I have next code:

#include <iostream>

class Example
{
public:
    Example()
    {
        std::cout
            << "constructor: "
            << std::hex
            << this
            << std::endl;
    }

    ~Example()
    {
        std::cout
            << "destructor:  "
            << std::hex
            << this
            << std::endl;
    }

    static Example foo()
    {
        Example ex;

        std::cout
            << "foo:         "
            << std::hex
            << &ex
            << std::endl;

        return ex;
    }
};


int
main()
{
    Example ex = Example::foo();
}

Mingw compiled program says: constructor: 0x22fe4f foo: 0x22fe4f destructor: 0x22fe4f

That is expected result for me programming only with wingw and g++ But when I tried to use Microsoft cl I got this: constructor: 00000000001BF750 foo: 00000000001BF750 destructor: 00000000001BF750 destructor: 00000000001BF790

Two destructor calls? Only one constructor call? Ok, foo create it's own object and call copy constructor on return. But why I need to copy it when compiler can put object in main function stack like mingw and put out pointer as argument to foo function by itself? Like this:

    // no return but `out` reference
    static void foo(Example &ex)
    {
        std::cout
            << "foo:         "
            << std::hex
            << &ex
            << std::endl;
    }
};


int
main()
{
    Example ex; // allocate memory in stack
    Example::foo(ex); // process/fill it
}

What's I do wrong or is there are any way to not call copy constructor and not writting code with out references?


Solution

  • Constructors are not the only way to create an object. A Copy Constructor and Move Constructor (C++11 Onwards) can do the same.

    In your case, when the return ex is executed, the instance created in the function is deleted and a new instance is created using Copy Constructor. you will get the print if you write the following code

    Example(const Example &) {
            std::cout << "Copy Constructor" << std::hex << this << std::endl;
        }
    

    The copy happens before the destruction of original object and hence you'll see this print before destructor.

    Why its not happening in some compilers?

    Because of a mechanism called RVO (Return value optimization), the compiler intelligently understand that you'll be using the same instance and hence it's being moved instead of being copied.

    Hope its clarifies.