I would like to understand why unique_ptr destructors require the type to be complete upon destruction while that isn't the case with shared_ptr. This blog from Howard Hinnant briefly mentions it has to do with static vs. dynamic deleters. I'm looking for a more detailed explanation of why that might be the case (it may be compiler implementation specific in which case an example would be helpful). With dynamic deleters, does it restrict the destructor from being inlined?
Howard Hinnant was simplifying. What he precisely meant was if you use the default deleter for std::unique_ptr, you need a complete type. For the default deleter, it simply calls delete for you.
The gist of static and dynamic deleters is
class A;
void static_delete(A* p)
{
delete p;
}
void (*dynamic_delete)(A*) = /* somehow */;
int main()
{
A* p = /* somehow */;
static_delete(p); // undefined behaviour
dynamic_delete(p); // maybe not
}
As long asdynamic_delete points to a function that's defined where A is also defined, you have well-defined behaviour.
To prevent undefined behaviour, the default deleter checks for a complete type, which may be implemented as
void default_delete(A* p)
{
static_assert(sizeof(A) > 0);
delete p;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With