Boost logo

Boost :

From: Sebastian Redl (sebastian.redl_at_[hidden])
Date: 2006-07-21 07:39:29


Oleg Abrosimov wrote:

>static void execute(Iterator*, LastIterator*, F f)
>{
> assert(std::uncaught_exception());
> typedef typename boost::mpl::deref<Iterator>::type item;
>
> try
> {
> throw;
> }
> //...
>}
>
>
uncaught_exception() always returns false in VC++6, so if you want the
thing to work there you need to put this assert under conditionals.

But actually, it will never work and always assert(). The standard says:

*Returns:*
    true after completing evaluation of a /throw-expression/ until either
    completing initialization of the /exception-declaration/ in the
    matching handler or after entering terminate()
    for eny reason other than an explicit call to terminate(). [/Note:/
    This includes stack unwinding --/end note/]

At the point you enter execute(), the matching handler (the catch(...)
outside) has completed initialization of its exception declaration.

The use case for uncaught_exception() is quite simple: it allows
destructors to take different actions depending on whether they're
destructed due to stack unwind or a different reason.
I've used it in a thin wrapper around jpeglib: there you have to wrap
the encoding/decoding process in matching function calls, with different
end calls depending on whether an error occurred. I wrote a sentry class
that calls the start function on construction and uses
uncaught_exception() to decide which of the end functions it should call
on destruction. If the guarded block exits with an exception, the error
abort function will be called, otherwise the normal decoding finished
function will be called.
Another option is for destructors that perform operations that could
fail. They could throw an exception in case of that failure, unless
they've determined, via uncaught_exception(), that an exception is
already pending. Then they don't throw, to avoid terminate() being called.

As a simple way of remembering when uncaught_exception() returns true,
simply remember that this snippet will always call terminate() instead
of actually throwing.

if(uncaught_exception()) throw 1;

Sebastian Redl


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk