I realise this is ill-advised, and I'm not proposing to do it, but I'm curious as to whether the following is actually formally illegal:
#include <iostream>
struct X
{
~X()
{
std::cout << "~X()\n";
}
};
int main()
{
X *x = new X;
//delete x;
x->~X();
::operator delete(x);
return 0;
}
It's my understanding that delete x;
is equivalent to invoking the destructor and then calling ::operator delete(x);
, but is it legal for me to do that manually according to the standard? I know this is a valid thing to when using placement new, but what about in the non-placement case? My hunch is that it might be illegal because delete
(and not operator delete
) has to be performed for each new
, but I'd be interested to know for sure.
I'm pretty sure that this is not standard compliant. Nowhere in the standard (that I'm aware of) does it say that the operand of delete p;
is passed directly to the deallocation function, and for delete []
it almost certainly isn't passed through unchanged.
It will probably work on all practical implementations, however.
For certain, you shouldn't be calling the global deallocation function explicitly. It's fine in your example, which doesn't have user-defined allocation and deallocation functions, but not in the general case (actually, is there any syntax for calling the class-specific deallocation function if it exists, and the global one otherwise?).
Also, in the general case, the pointer passed to the deallocation function is definitely not the operand of delete. Consider:
struct A
{
virtual ~A() {}
};
struct B1 : virtual A {};
struct B2 : virtual A {};
struct B3 : virtual A {};
struct D : virtual B1, virtual B2, virtual B3 {};
struct E : virtual B1, virtual D {};
int main( void )
{
B3* p = new D();
p->~B3(); // should be ok, calling virtually
operator delete(p); // definitely NOT OK
return 0;
}
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