gc classes and destructors

P

Peter Hemmingsen

Hi,

Below is a smal test program which create two objects deriving from
DataTable.

When running the 3 lines of code marked as Ex1 the destructor of DataTableEx
is never called,- why?

When running the 2 lines of code marked as Ex2 the first line fail
compilation claiming there is no destructor,- why ? (the second one force by
destructor to be called)

The documentation I've read says that the compiler will "wrap" my destructor
into a finalize method that should be called my the gc.

Your help is highly appreciated,- thanks

Peter Hemmingsen

#using <mscorlib.dll>
#using <System.dll>
#using <System.Data.dll>

using namespace System::Data;

public __gc class DataTableEx : public DataTable {
public:

DataTableEx():DataTable() {
System::Console::Write ("DataTableEx created\n");
};
~DataTableEx() {
System::Console::Write ("DataTableEx destroyed\n");
};
};

void main () {
DataTable* dt=new DataTableEx();
DataTableEx* dtex=new DataTableEx();

// ex 1
dt=0;
dtex=0;
System::GC::Collect();

// ex 2
delete dt; // compiler fails !!!
delete dtex;
}
 
B

Brandon Bray [MSFT]

Peter said:
When running the 3 lines of code marked as Ex1 the destructor of
DataTableEx is never called,- why?

To make sure things are clear, this is actually the finalizer that isn't
running. Unfortunately, the current syntax for C++ complicates the syntax
for writing a destructor actually generates both a destructor and a
finalizer. The destructor function that is emitted just supresses
finalization and then calls the finalizer. All the code that you write in
the class destructor goes into the finalizer function.

All that said, I have no idea why the CLR is not running the finalizers for
these objects. Studying the IL, there's absolutely no reason as far as I can
see for the behavior. I've opened a bug with the CLR.
When running the 2 lines of code marked as Ex2 the first line fail
compilation claiming there is no destructor,- why ? (the second one force
by destructor to be called)

The first class doesn't have a destructor, so there's no way to call it. The
second class (the one defined in C++) has a destructor. If you disassemble
the code using ildasm, you will see the __dtor function. That's why the
compiler lets you call it.

As soon as I hear back from the CLR about the finalizer problem, I'll let
you know.
 
P

Peter Hemmingsen

Hi Brandon,

Thanks a lot for your reply. I'm looking forward to hear from you.

BTW the problem only occur for classes deriving from DataTable, if I derive
from another class (such as Drawing::Image) the destructor is correctly
called.

Peter
 
B

Brandon Bray [MSFT]

Peter said:
BTW the problem only occur for classes deriving from DataTable, if I
derive from another class (such as Drawing::Image) the destructor is
correctly called.

Hi Peter,
The bug on this question is still open, but there is something to report.
The constructor for System::Data::DataTable calls SuppressFinalize. This is
why the finalizer is never called for anything that derives from DataTable.

As the bug is still open, I believe the question now is why the constructor
does that. If you must work around this problem, you can reregister the
object for finalization in the derived class's constructor.
 
P

Peter Hemmingsen

Hi Brandon,

Thanks for getting back. If there is a reason why it call SuppressFinalize
wouldn't it then be dangerous to reregister it?

Peter
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top