Should have said walk the class hierarchy (using reflection) - not the stack
;-) My fingers didn't type what my mind was thinking.

Regards,

Bob Lynch

-----Original Message-----
From: Moderated discussion of advanced .NET topics.
[mailto:[EMAIL PROTECTED]]On Behalf Of Robert Lynch
Sent: Monday, May 13, 2002 1:54 PM
To: [EMAIL PROTECTED]
Subject: Re: [ADVANCED-DOTNET] Interesting side effect (or bug based on
yo ur perspective) of compiler generated code for destructors


It wouldn't be enough for the compiler to just look at the dtor of the
object and skip empty ones. What actually gets generated includes a call to
the base classes finalizer as well. So it would have to walk the stack to
make sure no other class in the chain had a finalizer.

Regards,

Bob Lynch

-----Original Message-----
From: Moderated discussion of advanced .NET topics.
[mailto:[EMAIL PROTECTED]]On Behalf Of Jay Hilyard
Sent: Monday, May 13, 2002 8:01 AM
To: [EMAIL PROTECTED]
Subject: [ADVANCED-DOTNET] Interesting side effect (or bug based on your
perspective) of compiler generated code for destructors


Hi all,

 I was playing around with finalization and garbage collection the
other day and I had a thought.  Since a finalizer automatically insures
that objects are not garbage collected in generation zero, and since
destructor syntax in C# and managed C++ are used to declare finalizers,
what happens if you have an empty destructor?  Obviously it would be nice
if the compilers noticed that your destructor is empty and thus did not
generate the code for a finalizer which makes your objects stick around
longer.  Alas, this is not the case as the following code examples show.

No major issue but something I thought was worth passing along.  I could
see this being an issue for people writing code generators who are used to
working in C++ who might forget that a destructor in unmanaged C++ is not
the same as a "destructor/finalizer" in managed C++.

Enjoy

Jay


Code examples for C# and MCPP

C#
class FinalizedClass
{
 static void Main(string[] args)
 {

 }
 // provide empty destructor
 ~FinalizedClass()
 {
 }
}

turns into the following IL (as you can see in ILDASM)

.method family hidebysig virtual instance void
        Finalize() cil managed
{
  // Code size       10 (0xa)
  .maxstack  1
  .try
  {
    IL_0000:  leave.s    IL_0009
  }  // end .try
  finally
  {
    IL_0002:  ldarg.0
    IL_0003:  call       instance void [mscorlib]System.Object::Finalize()
    IL_0008:  endfinally
  }  // end handler
  IL_0009:  ret
} // end of method FinalizedClass::Finalize


Managed C++

__gc class FinalizedClass
{
 FinalizedClass(){};
 ~FinalizedClass(){};
};


turns into the following (more efficient and yet still present) IL

.method family virtual instance void  Finalize() cil managed
{
  // Code size       1 (0x1)
  .maxstack  0
  IL_0000:  ret
} // end of method FinalizedClass::Finalize

You can read messages from the Advanced DOTNET archive, unsubscribe from
Advanced DOTNET, or
subscribe to other DevelopMentor lists at http://discuss.develop.com.

You can read messages from the Advanced DOTNET archive, unsubscribe from
Advanced DOTNET, or
subscribe to other DevelopMentor lists at http://discuss.develop.com.

You can read messages from the Advanced DOTNET archive, unsubscribe from Advanced 
DOTNET, or
subscribe to other DevelopMentor lists at http://discuss.develop.com.

Reply via email to