Re: Destructor: not gauranteed to be called?
- From: "Peter Oliphant" <poliphant@xxxxxxxxxxxxxxxx>
- Date: Tue, 31 Jan 2006 09:44:37 -0800
/rant on
I'm sorry, but this is VERY new info to me, and I've been doing OOP for
about 15 years! Personally, I think it is against the whole concept of a
destructor. Why bother to ever create one if there is no gaurantee it will
be called? To me (IMHO), OOP should have this pact with the programmer. The
constructor is to set up the creation of an instance. The destructor is for
clean-up. Thus, the destructor should be gauranteed to be called SOMETIME,
at the very latest at application exit. Otherwise I feel the C++ laguage is
at fault for anything my destructor was meant to make sure wasn't left in a
bad state, since THAT's what I wrote the destructor for, and thought it was
responsible for making sure eventually happened.
Let me make this clear. I have always realized that when GC wasn't in play
that if I created something (then via 'new') I had to destruct it manually
to avoid memory leaks. That is, it was never gauranteed the destructor would
be called unless I invoked it via a delete call. But, with the introduction
of GC, anything created as a gc object shouldn't need to be destructed
manually, as the application is suppose to keep track of whether something
is being used anymore by anyone before GC destroys it. But I always assumed
it would destroy it the same way one would manually destroy it, by calling
it's destructor. Could someone explain to me why NOT calling the destructor
upon GC destroying the object would EVER be a GOOD thing?
What I see emerging is this. GC was created to help with the concept that
destruction of an object is tough to do when who 'owns' it is unclear, or
when it is unclear whether everyone's done with it. This caused memory leaks
in the case that 'nobody' took final responsibility (or couldn't based on
the info available). But the solution to this is now generating another
issue. Lack of reliable destruction! Destruction is now not gauranteed at
any time you don't specifically delete it. BUT WAIT! The whole point of GC
was to AVOID having to know when to do delete. So, if we are forced to do
delete to insure the destructor get run, then what did we gain from
introducing GC? That is, if we now still have to delete at the right time,
this implies we know the instance is free to be destroyed. Thus, we lose the
advantage we got. Or more precisely, we have add complication that
introduces more possible pitfalls, and we are STILL required to tell the
application when to destroy something if we want our destructors have any
reliable meaning!
Further, this is now causing aditional problems. I reported a bug that is
very nasty via the feedback center. The bug is this: Try creating two
classes, both ref. Now create 142 stack sematic variables of one class in
the other. Oh yeah, be sure the classes have destructors. Put ZERO code in
these classes. Guess what? It won't compile, and will return a 'program too
complex' error! It further explains it can't build the destructor. Now,
comment out the destructor in the class the 142 instances are based on. NOW
it compiles! So, they have introduced complexity to such a point with the
way it deals with destructors that it can't handle it past 142 members! I
don't see that as progress...
And, again possibly showing my ignorance, when did finalizers come into
play? Is this part of the C++ standard?
Basically, I think things have gotten so complicated in this destructor area
that we have just traded one set of problems for another. If I can't rely on
the code I write specifically for the purpose of tidying things up from ever
getting called, it aint my fault if stuff isn't returned back to normal once
my code is done running. Heaven forbid anyone put the 'return the system
back' code in the destructor of an application based on a single class...
; )
/rant off
Ok I feel much better now... lol
[==P==]
PS - here is link to bug I reported:
http://lab.msdn.microsoft.com/productfeedback/viewfeedback.aspx?feedbackid=3f6131a9-7d0a-496a-b8a0-44bd02f398c6
"Carl Daniel [VC++ MVP]" <cpdaniel_remove_this_and_nospam@xxxxxxxxxxxxxxx>
wrote in message news:efPulGoJGHA.3144@xxxxxxxxxxxxxxxxxxxxxxx
> Peter Oliphant wrote:
>> I'm programming in VS C++.NET 2005 using cli:/pure syntax. In my code
>> I have a class derived from Form that creates an instance of one of
>> my custom classes via gcnew and stores the pointer in a member.
>> However, I set a breakpoint at the destructor of this instance's
>> class and it was never called!!! I can see how it might not get
>> called at a deterministic time. But NEVER?
>>
>> So, I guess I need to know the rules about destructors. I would have
>> thought any language derived from C++ would always guarantee the
>> destructor of an instance of a class be called at some time,
>> especially if created via [gc]new and stored as a pointer.
>
> Why would you think that when C++ makes no similar guarantee for pure
> native C++? The destructor for an object on the heap is called when and
> if you call delete on a pointer to that object. The situation is no
> different for C++/CLI with respect the to destructor (which is
> IDisposable::Dispose for C++/CLI).
>
>>
>> Yes, I think I can deterministically destruct it via 'delete' and
>> setting to nullptr. But the point still kinda freaks me that the
>> destructor is no longer gauranteed to EVER be called. I feel like I
>> should be worried since it is sometimes important to do other things
>> besided freeing up memory in a destructor. In my case I discovered it
>> becuase I'm communicating through a serial port which I change the
>> baud rate from the current speed, but then changed it back in the
>> destructor - only to find out the destructor was NEVER called! Hence,
>> the port died, and MY program wouldn't work on subsequent runs since
>> it assumed the port had been returned to the same baud (and hence
>> couldn't communicate with it anymore).
>> So, again, why is the destructor no longer gauranteed to be called,
>> and what are these new rules? Or am I being ignorant, and C++ never
>> made such assurances. Inquiring minds want to know! : )
>
> They're not new rules - it's the nature of objects on the heap. For
> managed object on the GC heap, the Finalizer MAY be called if you don't
> delete the object, but the CLR doesn't guarantee that finalizers are ever
> called either.
>
> -cd
>
>
.
- Follow-Ups:
- Re: Destructor: not gauranteed to be called?
- From: Bo Persson
- Re: Destructor: not gauranteed to be called?
- From: Arnaud Debaene
- Re: Destructor: not gauranteed to be called?
- References:
- Destructor: not gauranteed to be called?
- From: Peter Oliphant
- Re: Destructor: not gauranteed to be called?
- From: Carl Daniel [VC++ MVP]
- Destructor: not gauranteed to be called?
- Prev by Date: Re: Destructor: not gauranteed to be called?
- Next by Date: Re: Destructor: not gauranteed to be called?
- Previous by thread: Re: Destructor: not gauranteed to be called?
- Next by thread: Re: Destructor: not gauranteed to be called?
- Index(es):
Relevant Pages
|