Re: Exception unwinding base destructor called - why?
From: Andre Kostur (nntpspam_at_kostur.net)
Date: 06/24/04
- Next message: cyper: "Re: Default constructor/destructor"
- Previous message: ctick: "Default constructor/destructor"
- In reply to: Douglas Peterson: "Exception unwinding base destructor called - why?"
- Next in thread: Douglas Peterson: "Re: Exception unwinding base destructor called - why?"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Thu, 24 Jun 2004 06:32:02 GMT
"Douglas Peterson" <Tergiver@nospam.msn.com> wrote in
news:Uradnc5W-JW170fdRVn-vw@comcast.com:
> Take a look at this code, it looks funny as its written to be as short
> as possible:
>
> -- code --
> struct Base
> {
> ~Base() { *((char*)0) = 0; }
> };
>
> struct Derived : public Base
> {
> Derived() { throw 1; }
> };
>
> int main(int,char**)
> {
> try { new Derived; }
> catch (int) { }
> return 0;
> }
> -- code --
>
> Now don't get excited about the *((char*)0) = 0, I'm just using that
> as a kind of compiler independent, hard coded breakpoint. I want to
> verify that the destructor is in fact getting called without relying
> on a debugger set breakpoint which can sometimes not occur, or the
> code be optimized out so that there is no point to break on.
Not necessarily safe. Dereferencing a NULL (or 0) pointer invokes
"Undefined Behaviour". The compiler could theoretically "optimize" out
that line too... (the compiler could also theoretically format your hard
drive too....)
> So what are we looking at?
>
> We are creating an instance of Derived inside an exception handler.
> During construction Derived throws an exception and the handler's
> unwinding mechanism is calling the destructor for the base class.
>
> My question is: Why?
>
> Where is the logic in partially deconstructing an aggregate object
> that's signaling it cannot be constructed by way of an exception? If
> you move the ...ahem... breakpoint to Derived's destructor, that never
> gets called. Makes sense not to deconstruct an object that's not fully
> constructed, so again, why partially deconstruct it?
Before the body of the Derived constructor can be invoked, the Base
"class" must have completed constructing (as well as all members of the
base class, as well as all members of Dervied too...). During your
Derived constructor, you throw an exception. This will cause all of the
parts of Derived that had been completely constructed (ie: the Base
portion (which also includes Base's members) and all members of Derived)
will be destructed, in the reverse order in which their constructions
completed (so it would be Derived members, Base destructor body, Base
members).
> The other thing that doesn't make sense to me is that this object is
> not being created on the stack, so why would *any* destructor be
> called by the unwinding mechanism? There is no call to delete anywhere
> in the code, so what makes the compiler think it should be
> deconstructed at all?
See above.... in C++, objects don't care whether they're on the stack,
heap, shared memory, or any other location (<pedantic mode on>There is no
such thing as a stack in Standard C++</pedantic mode off>). When the
object's lifespan begins, the constructors are invoked. When the
object's lifespan ends, the destructors are invoked.
- Next message: cyper: "Re: Default constructor/destructor"
- Previous message: ctick: "Default constructor/destructor"
- In reply to: Douglas Peterson: "Exception unwinding base destructor called - why?"
- Next in thread: Douglas Peterson: "Re: Exception unwinding base destructor called - why?"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|