Problem
The destructor gets called twice in the following code:
class Foo
{
public:
~Foo()
{
std::cout << "Destructor called\n";
}
Foo& operator=(const Foo& other)
{
std::cout << "Assignment called\n";
return *this;
}
};
Foo foo()
{
return Foo();
}
int main()
{
foo();
return 0;
}
Output:
Destructor called
Destructor called
I suspect this is due to some implicit call to an assignment operator or a copy constructor. I cannot tell if the copy constructor gets called as adding a constructor of any kind magically solves the problem (as explained further down), but at least the assignment operator does not get called.
And as mentioned, if I add a constructor, the problem goes away:
class Foo
{
public:
Foo()
{
std::cout << "Constructor called\n";
}
Foo(const Foo& other)
{
std::cout << "Copy constructor called\n";
}
~Foo()
{
std::cout << "Destructor called\n";
}
Foo& operator=(const Foo& other)
{
std::cout << "Assignment called\n";
return *this;
}
};
The output changes into:
Constructor called
Destructor called
The problem also goes away if I return a reference instead of an object (but results in a "returning address of local or temporary variable" warning):
Foo& foo()
{
return Foo();
}
Question
Why is the destructor called twice, and why is the behavior different when using a default constructor or not? Is there a logical explanation or could it be a mistake by the compiler?
I'm using MSVC 2013 if it could make any difference.