I am trying to figure out whether it's safe to delete an object created in module A from module B using a virtual destructor.
When using MS C++ compiler, deleting an object having a virtual destructor results in just a single vtable call and the underlying free()
call is performed inside it (i.e. in the same module that created the object, i.e. safe).
The questions is: is it just the current MS implementation, or is it guaranteed in some standard or document and can be safely relied on?
Here's the example of a disassembled virtual destructor call in VS2010:
int _tmain(int argc, _TCHAR* argv[])
{
test *p = new test();
008A1030 push 4
008A1032 call dword ptr [__imp_operator new (8A20A0h)]
008A1038 add esp,4
008A103B test eax,eax
008A103D je wmain+19h (8A1049h)
008A103F mov dword ptr [eax],offset test::`vftable' (8A2100h)
008A1045 mov ecx,eax
008A1047 jmp wmain+1Bh (8A104Bh)
008A1049 xor ecx,ecx
__asm int 3;
008A104B int 3
delete p;
008A104C test ecx,ecx
008A104E je wmain+28h (8A1058h)
008A1050 mov eax,dword ptr [ecx]
008A1052 mov edx,dword ptr [eax]
008A1054 push 1
008A1056 call edx
__asm int 3;
008A1058 int 3
return 0;
008A1059 xor eax,eax
}
Well, the caller isn't going to know the type of the object? And without knowing that type, how could the caller call Derived::operator delete
? Only Derived::~Derived
can know whether Derived::operator delete
must be called instead of the generic ::operator delete
.
Hence, we can deduce that the caller cannot call ::operator delete
.
It's unspecified whether operator delete
later calls free()
, but that's a detail anyway.