Topic: Recursive exceptions


Author: b91926@fsui02.fnal.gov (David Sachs)
Date: 1997/02/15
Raw View
I can find nothing in the draft C++ standard either permitting or
prohibiting recursive exceptions.

I use the term "recursive exception" for the situation described
in the following paragraphs:

After an exception is thrown, the runtime stack is unwornd while]
searching for a proper handler. As part of the unwinding process
destructors are called for class objects in the stack.

Suppose that a destructor called in this manner, or a function
called from such a destructor contains a try block. If something
within the scope of such a try block throws an exception, then
at that point, there are 2 uncaught exceptions being processed.
I call the second exception a "recursive excpetion". If someone
has a better term for this, please suggest it.

Obviously, the second exception must be caught and processed by
an exception handler within the destructor or a function it calls;
the standard properly specifies that having the destructor terminate
by throwing an exception is an unconditionally fatal run-time error.

The draft standard does not specify whether a properly caught
recursive exception is standard-conforming.

At least one commercially available C++ compiler supports recursive
exceptions.
--
** The Klingons' favorite food was named by the first earthling to see it **
David Sachs - Fermilab, MSSG MS369 - P. O. Box 500 - Batavia, IL 60510
Voice: 1 630 840 3942      Department Fax: 1 630 840 3785
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Stephen.Clamage@eng.sun.com (Steve Clamage)
Date: 1997/02/16
Raw View
In article j6d@fsui02.fnal.gov, b91926@fsui02.fnal.gov (David Sachs) writes:
>I can find nothing in the draft C++ standard either permitting or
>prohibiting recursive exceptions.
>
>I use the term "recursive exception" for the situation described
>in the following paragraphs:
>
>After an exception is thrown, the runtime stack is unwornd while]
>searching for a proper handler. As part of the unwinding process
>destructors are called for class objects in the stack.
>
>Suppose that a destructor called in this manner, or a function
>called from such a destructor contains a try block. If something
>within the scope of such a try block throws an exception, then
>at that point, there are 2 uncaught exceptions being processed.
>I call the second exception a "recursive excpetion". If someone
>has a better term for this, please suggest it.
>
>Obviously, the second exception must be caught and processed by
>an exception handler within the destructor or a function it calls;
>the standard properly specifies that having the destructor terminate
>by throwing an exception is an unconditionally fatal run-time error.
>
>The draft standard does not specify whether a properly caught
>recursive exception is standard-conforming.

It says so indirectly. It describes the behavior of throw and catch
clauses, and is very careful to say only that *exiting* a destructor
via an uncaught exception is an error if it occurs during the handling
of another exception. If the exception doesn't escape, no rule is violated.

---
Steve Clamage, stephen.clamage@eng.sun.com
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Oleg Zabluda <zabluda@math.psu.edu>
Date: 1997/02/16
Raw View
David Sachs <b91926@fsui02.fnal.gov> wrote:
: I can find nothing in the draft C++ standard either permitting or
: prohibiting recursive exceptions.

What you call "recursive exceptions" is prohibited by the Draft Standard.
If an exception is thrown after some other exception is thrown,
bu not caught yet, terminate() will be called. The Draft Standard defines
a function called is_exception_pending() or something like this,
which returns true in between an exception is called and caught,
specifically to help users to avoid this situation.

Oleg.
--
Life is a sexually transmitted, 100% lethal disease.
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: fjh@murlibobo.cs.mu.OZ.AU (Fergus Henderson)
Date: 1997/02/17
Raw View
Oleg Zabluda <zabluda@math.psu.edu> writes:

>David Sachs <b91926@fsui02.fnal.gov> wrote:
>: I can find nothing in the draft C++ standard either permitting or
>: prohibiting recursive exceptions.
>
>What you call "recursive exceptions" is prohibited by the Draft Standard.

Please quote chapter and verse, because I'm sure you're wrong.

>If an exception is thrown after some other exception is thrown,
>bu not caught yet, terminate() will be called.

No, that's not correct.

 |   15.5.1  The terminate() function                    [except.terminate]
 |
 | 1 In the following situations exception handling must be  abandoned  for
 |   less subtle error handling techniques:
 |
 |   --when  the  exception handling mechanism, after completing evaluation
 |     of the expression to be thrown but before the  exception  is  caught
 |     (_except.throw_),  calls  a user function that exits via an uncaught
 |     exception,

Note that terminate is only called if a user function that is called
by the exception handling mechanism (e.g. a destructor called during
stack unwinding) *exits* via an uncaught exception.  If the user
function throws exceptions internally, that is fine, just so long as it
catches them internally.

>The Draft Standard defines
>a function called is_exception_pending() or something like this,
>which returns true in between an exception is called and caught,
>specifically to help users to avoid this situation.

The function is called `uncaught_exception()'.
It is indeed to help users avoid calling terminate(),
but normally it would be checked in a `catch' statement
in a destructor, to make sure that exceptions don't escape,
rather than checking it before each throw() statement.
For example:

 Foo::~Foo() {
  try {
   do_some_complicated_cleanup();
  } catch (...) {
   if (uncaught_exception()) {
    // oh-oh, better not rethrow, otherwise
    // terminate() will be called.  Just log it.
    log_current_exception();
   } else {
    throw;
   }
  }
 }

Putting checks for uncaught_exception() in all destructors that might
throw exceptions is probably a lot more feasible than putting such
checks around all throw() statements that might possibly be called from
destructors.  Even if you did check for uncaught_exception() before
throwing, what could you do if it were true?  In general there may
be no way of satisfying your contact other than throwing an exception
or calling terminate() anyway.  Hence it is very important that the
draft allows recursive exceptions.

--
Fergus Henderson <fjh@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3         |     -- the last words of T. S. Garp.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]