Consider the following code snippet. The destructor of boost::scoped_ptr is invoked at the end of the main function. The destructor uses boost::checked_delete to deallocate the encapsulated Widget pointer.
#include <boost/scoped_ptr.hpp>
#include <iostream>
class Widget;
Widget *make_widget();
int main()
{
boost::scoped_ptr<Widget> sp(make_widget());
// std::cout << sizeof(Widget) << std::endl;
}
class Widget
{
public:
Widget() {}
~Widget() { std::cout << "Widget destructor called." << std::endl; }
};
Widget *make_widget()
{
return new Widget;
}
I expected this code to fail to compile as the class Widget is incomplete at the point the destructor of scoped_ptr<Widget>
is invoked. However this compiles cleanly on g++ 4.8 and Visual Studio 2010. Note the commented statement with the sizeof(Widget)
expression in the main function. If I uncomment it, it will fail to compile implying that Widget
must be incomplete at that point.
What is the correct explanation for this behavior?
EDIT: Some answers (now deleted) pointed to undefined behavior but I would have expected the use of checked_delete in scoped_ptr
's destructor to cause a compilation failure. FWIW, I'm using Boost 1.55.
check_delete
to catch the use of an incomplete type so I am pretty surprised this compile withsizeof
commented. – Lyndystruct SP { ~SP() { depete ptr; } /* ... */ };
orstruct SP { ~SP(); /* ... */ };
. If the destructor isn't inline, then it doesn't need to be known at the time where it's called, and so the type ofptr
is also not needed. – Scleroma