I have this code:
class Class {
public:
virtual ~Class() {}
};
int main()
{
Class* object = new Class();
delete object;
}
which I compile with Visual C++ 10 and get this disassembly for delete object
statement:
delete object;
test eax,eax
je wmain+23h (401041h)
mov edx,dword ptr [eax]
push 1
mov ecx,eax
call dword ptr [edx]
and this for the actual destructor:
Class::`scalar deleting destructor':
test byte ptr [esp+4],1
push esi
mov esi,ecx
mov dword ptr [esi],offset Class::`vftable' (402100h)
je Class::`scalar deleting destructor'+18h (401018h)
push esi
call dword ptr [__imp_operator delete (4020A8h)]
pop ecx
mov eax,esi
pop esi
ret 4
What is that push 1
doing at the call site and why is the test
at the destructor entry point checking for that value and conditionally bypass call to operator delete()
?
c++-cli
– Martellatotest eax,eax
is checking for a null pointer. Not sure why it's in release code. – Adroitdelete null;
, and there's a chance thenew
returned a null so it's probably not allowed to optimise it away. – Danieunew
never returnsnull
, yet Visual C++ still checks that. – Cookerynew
is used withoutnothrow
and therefore can't return null and thereforedelete
is done on a non-null pointer. The check can be eliminated, just Visual C++ fails to do so. – Cookery