Tale of the __dtor method and the delete operator
Last week, I was reviewing the Managed C++ MOC course as I was scheduled to give it to an ISV. Something I read triggered my curiosity.
I was wondering what
delete p ; delete p ;
would mean in Managed C++ as I know the second call is undefined behaviour in Standard C++. The memory block is gone after all.
So I followed what was going on under the VS.NET debugger and I realized that all it does is calling the __dtor member that in turn calls System::GC::SuppressFinalize and then the Finalize method (the actual code specified in your Managed C++ destructor).
As p still refers to a block of memory in the Managed Heap, you could potentially call delete multiple times without having bad side effects. (depends on how robust/paranoiac the destructor/Finalize method code is I guess)
I can even define that method in a C# class and now, I can delete it from Managed C++.
// C#
public class Class1
{
public Class1()
{
}
public void __dtor()
{
Console.WriteLine( "\"C++ Destructor\"" ) ;
}
}
}
// MC++
ToDelete::Class1 * pClass1 = new ToDelete::Class1() ;
delete pClass1 ;
Not that I would advise people to do this: let's stick to the IDisposable pattern. Have you heard about the deterministic cleanup feature in Whidbey MC++?
Then, out of curiosity, I tried a query on Google __dtor +site:microsoft.com and well, all I deduce is that a lot of things in Longhorn are written in MC++!
But I did not find any good article/doc about that __dtor thing.
Later, I went where I should have started: ILDasm.
.method public instance void __dtor() cil managed
{
// Code size 13 (0xd)
.maxstack 1
IL_0000: ldarg.0
IL_0001: call void [mscorlib]System.GC::SuppressFinalize(object)
IL_0006: ldarg.0
IL_0007: callvirt instance void TestClass::Finalize()
IL_000c: ret
} // end of method TestClass::__dtor
I wonder if all I found and just wrote is correct. I'll check with the C++ team.
What is the value of all this? Well, as C++ developers, we like to understand all the details about what's going on behind the fence, don't we?
Which remind me of another topic for an entry: the need to look at details (IL) from time to time if you want performance from you MC++/C#/VB.NET software.
Arrivederci et à demain, si on le veut bien.