PC Review


Reply
Thread Tools Rate Thread

How to check from destructor whether it was called due to exception or normal exit from the scope?

 
 
Antonio
Guest
Posts: n/a
 
      9th Jul 2004
Hi, everybody

Is there a reliable way of detecting whether destructor of a local object
was called due to stack unwind (exception) or normal exit from the scope?
This check has to be made inside destructor of this local object. If there
is no portable C++ way of doing this, hacks for Windows and/or MSVC6
generated code (with checking some registers etc.) will do.

Thanks in advance,
Antonio


 
Reply With Quote
 
 
 
 
Simon Trew
Guest
Posts: n/a
 
      9th Jul 2004
"Antonio" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> Hi, everybody
>
> Is there a reliable way of detecting whether destructor of a local object
> was called due to stack unwind (exception) or normal exit from the scope?


No.

> This check has to be made inside destructor of this local object. If there
> is no portable C++ way of doing this, hacks for Windows and/or MSVC6
> generated code (with checking some registers etc.) will do.


If you really need it (and I can't think why), have a "prematureDestruction"
flag on your object which you set to true by default and false as the last
statement in your try block.


 
Reply With Quote
 
Sergei
Guest
Posts: n/a
 
      9th Jul 2004
bool uncaught_exception( );

"Antonio" <(E-Mail Removed)> wrote in message news:(E-Mail Removed)...
> Hi, everybody
>
> Is there a reliable way of detecting whether destructor of a local object
> was called due to stack unwind (exception) or normal exit from the scope?
> This check has to be made inside destructor of this local object. If there
> is no portable C++ way of doing this, hacks for Windows and/or MSVC6
> generated code (with checking some registers etc.) will do.
>
> Thanks in advance,
> Antonio

 
Reply With Quote
 
Antonio
Guest
Posts: n/a
 
      9th Jul 2004
Hi, everybody

I've just found the answer to the question myself -
std::uncaught_exception() from standard library does the job. As Stroustroup
writes this functionality might be needed in those cases when you want to
make sure that you don't throw from destructor when destructor was called
because of stack unwind (this situation is considered as a failure of the
exception-handling mechanism in C++ and std::terminate() is called in such
cases). In our case we needed it in a sort of tracer object that is
instantiated at the beginning of the function to log entering and leaving
the function, time of it took for execution and whether execution completed
normally or due to exception thrown.

Kind regards,
Antonio

"Antonio" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> Hi, everybody
>
> Is there a reliable way of detecting whether destructor of a local object
> was called due to stack unwind (exception) or normal exit from the scope?
> This check has to be made inside destructor of this local object. If there
> is no portable C++ way of doing this, hacks for Windows and/or MSVC6
> generated code (with checking some registers etc.) will do.
>
> Thanks in advance,
> Antonio
>
>



 
Reply With Quote
 
Simon Trew
Guest
Posts: n/a
 
      9th Jul 2004
But what if your object is created inside another one? e.g.

struct B
{
int x;
~B();
};

struct A()
{
B b;
~A();
};

A::~A()
{
if (uncaught_exception())
{
// After this call, b.~B() will be called with uncaught_exception()
== true
// But do we consider b to be being "normally" destroyed or
destroyed because of an exception?
};
};

"Antonio" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> Hi, everybody
>
> I've just found the answer to the question myself -
> std::uncaught_exception() from standard library does the job. As

Stroustroup
> writes this functionality might be needed in those cases when you want to
> make sure that you don't throw from destructor when destructor was called
> because of stack unwind (this situation is considered as a failure of the
> exception-handling mechanism in C++ and std::terminate() is called in such
> cases). In our case we needed it in a sort of tracer object that is
> instantiated at the beginning of the function to log entering and leaving
> the function, time of it took for execution and whether execution

completed
> normally or due to exception thrown.
>
> Kind regards,
> Antonio
>
> "Antonio" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
> > Hi, everybody
> >
> > Is there a reliable way of detecting whether destructor of a local

object
> > was called due to stack unwind (exception) or normal exit from the

scope?
> > This check has to be made inside destructor of this local object. If

there
> > is no portable C++ way of doing this, hacks for Windows and/or MSVC6
> > generated code (with checking some registers etc.) will do.
> >
> > Thanks in advance,
> > Antonio
> >
> >

>
>



 
Reply With Quote
 
Antonio
Guest
Posts: n/a
 
      9th Jul 2004
If B is a part of A and A is being destroyed because of stack unwind
(exception somewhere), then B is also destroyed because of stack unwind so
destructor in B can also do necessary checks if needed.

std::uncaught_exception() will return false again when this thrown exception
is handled by one of the callers on the stack.

Regards,
Antonio

"Simon Trew" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> But what if your object is created inside another one? e.g.
>
> struct B
> {
> int x;
> ~B();
> };
>
> struct A()
> {
> B b;
> ~A();
> };
>
> A::~A()
> {
> if (uncaught_exception())
> {
> // After this call, b.~B() will be called with

uncaught_exception()
> == true
> // But do we consider b to be being "normally" destroyed or
> destroyed because of an exception?
> };
> };
>
> "Antonio" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
> > Hi, everybody
> >
> > I've just found the answer to the question myself -
> > std::uncaught_exception() from standard library does the job. As

> Stroustroup
> > writes this functionality might be needed in those cases when you want

to
> > make sure that you don't throw from destructor when destructor was

called
> > because of stack unwind (this situation is considered as a failure of

the
> > exception-handling mechanism in C++ and std::terminate() is called in

such
> > cases). In our case we needed it in a sort of tracer object that is
> > instantiated at the beginning of the function to log entering and

leaving
> > the function, time of it took for execution and whether execution

> completed
> > normally or due to exception thrown.
> >
> > Kind regards,
> > Antonio
> >
> > "Antonio" <(E-Mail Removed)> wrote in message
> > news:(E-Mail Removed)...
> > > Hi, everybody
> > >
> > > Is there a reliable way of detecting whether destructor of a local

> object
> > > was called due to stack unwind (exception) or normal exit from the

> scope?
> > > This check has to be made inside destructor of this local object. If

> there
> > > is no portable C++ way of doing this, hacks for Windows and/or MSVC6
> > > generated code (with checking some registers etc.) will do.
> > >
> > > Thanks in advance,
> > > Antonio
> > >
> > >

> >
> >

>
>



 
Reply With Quote
 
Jason Winnebeck
Guest
Posts: n/a
 
      9th Jul 2004
Is the following code not sufficient (or practical) for your case?

int func() {
try {
//code
} catch ( ... ) {
//abnormal exit
throw;
}
}

Or it seems maybe you are just using this tracer object for quick
debugging of functions, and the tracer is a one-line solution? That
seems OK if used for debugging.

Jason

Antonio wrote:
> cases). In our case we needed it in a sort of tracer object that is
> instantiated at the beginning of the function to log entering and leaving
> the function, time of it took for execution and whether execution completed
> normally or due to exception thrown.

 
Reply With Quote
 
Antonio
Guest
Posts: n/a
 
      9th Jul 2004
The difference is that this code traps exception from "outside". What you
will know with this, is that somewhere in the code inside try-block there
was an exception thrown. But by the moment you fall into the catch-block,
destructors of local objects, created before exception was thrown, will
already be executed. The problem is that we need to know
_inside_those_destructors_ that they are executed because exception was
thrown and _not_in_the_context_ where those objects were instantiated.

Kind regards,
Antonio

"Jason Winnebeck" <(E-Mail Removed)> wrote in message
news:#(E-Mail Removed)...
> Is the following code not sufficient (or practical) for your case?
>
> int func() {
> try {
> //code
> } catch ( ... ) {
> //abnormal exit
> throw;
> }
> }
>
> Or it seems maybe you are just using this tracer object for quick
> debugging of functions, and the tracer is a one-line solution? That
> seems OK if used for debugging.
>
> Jason
>
> Antonio wrote:
> > cases). In our case we needed it in a sort of tracer object that is
> > instantiated at the beginning of the function to log entering and

leaving
> > the function, time of it took for execution and whether execution

completed
> > normally or due to exception thrown.



 
Reply With Quote
 
Doug Harrison [MVP]
Guest
Posts: n/a
 
      9th Jul 2004
Antonio wrote:

>Hi, everybody
>
>I've just found the answer to the question myself -
>std::uncaught_exception() from standard library does the job. As Stroustroup
>writes this functionality might be needed in those cases when you want to
>make sure that you don't throw from destructor when destructor was called
>because of stack unwind (this situation is considered as a failure of the
>exception-handling mechanism in C++ and std::terminate() is called in such
>cases).


In general, dtors should not be allowed to exit via an exception.

>In our case we needed it in a sort of tracer object that is
>instantiated at the beginning of the function to log entering and leaving
>the function, time of it took for execution and whether execution completed
>normally or due to exception thrown.


The function uncaught_exception would be useful for that. It cannot be used,
however, to determine if it is safe to throw an exception. For example, if
uncaught_exception() is true, it remains true even inside a try block, whose
catch block catches all exceptions that might be thrown. Note also that in
VC6 and earlier, uncaught_exception() always returns false.

--
Doug Harrison
Microsoft MVP - Visual C++
 
Reply With Quote
 
Igor Tandetnik
Guest
Posts: n/a
 
      9th Jul 2004
"Doug Harrison [MVP]" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)
> Note also that in VC6 and earlier,
> uncaught_exception() always returns false.


It's still listed as not being implemented and always returning false:

http://msdn.microsoft.com/library/en...eturnstrue.asp

Are you saying it actually works in VC7.1? I haven't tried it myself.
--
With best wishes,
Igor Tandetnik

"For every complex problem, there is a solution that is simple, neat,
and wrong." H.L. Mencken


 
Reply With Quote
 
 
 
Reply

Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Destructor is not called Eitan Microsoft C# .NET 4 16th Jan 2008 02:05 AM
destructor not being called Andy Fish Microsoft C# .NET 7 2nd Oct 2007 12:52 AM
Destructor is not called when an exception is propagating from unmanaged to mixed code. caa@aurigma.com Microsoft VC .NET 1 17th Jul 2007 02:19 PM
Re: how to check if Monitor::Exit has been called Carl Daniel [VC++ MVP] Microsoft VC .NET 2 11th Nov 2006 06:41 PM
how to check if Monitor::Exit has been called Ian Microsoft VC .NET 2 10th Nov 2006 10:12 PM


Features
 

Advertising
 

Newsgroups
 


All times are GMT +1. The time now is 08:49 PM.