catch(...) and forced unwind

Jason Merrill jason@redhat.com
Tue Dec 16 00:52:00 GMT 2003


On Mon, 15 Dec 2003 18:32:10 -0500, David Abrahams <dave@boost-consulting.com> wrote:

> Jason Merrill <jason@redhat.com> writes:
>
> I have to admit I am not familiar with the specification of iostreams
> - in fact, I try to avoid getting familiar with that part of the
> standard. I have been going on the assumption that the specification
> of badbit handling counts as "otherwise specified".  If I am wrong
> (and I may be) then I take it all back.  Am I?  

  27.6.1  Input streams                              [lib.input.streams]

2 Two  groups of member function signatures share common properties: the
  formatted input functions (or extractors) and  the  unformatted  input
  functions.  Both  groups  of input functions are described as if they
  obtain (or extract) input characters by calling  rdbuf()->sbumpc()  or
  rdbuf()->sgetc().  They may use other public members of istream.

3 If  rdbuf()->sbumpc()  or rdbuf()->sgetc() returns traits::eof(), then
  the input function, except as explicitly  noted  otherwise,  completes
  its    actions    and   does   setstate(eofbit),   which   may   throw
  ios_base::failure (_lib.iostate.flags_), before returning.

4 If one of these called functions  throws  an  exception,  then  unless
  explicitly  noted  otherwise,  the input function sets badbit in error
  state.  If badbit is on in exceptions(), the input  function  rethrows 
  the exception without  completing its  actions, otherwise  it does not
  throw anything and proceeds as if the called function had  returned  a
  failure indication.

The text for output streams is similar.  I note, though I concede that this
is something of a perverse reading of the standard, that although this says
that the functions don't rethrow, nothing precludes them from throwing
implementation-defined exceptions of their own.

Also, this restriction only applies to the {un,}formatted i/o functions,
not to any other operations.

I would like to loosen the passage quoted above to allow rethrowing some
exceptions as defined by the implementation.  I don't think this change
would break anyone's code, since the existing guarantee is so weak.

>> Actually, this is backwards -- the standard doesn't allow the C I/O
>> functions to throw any exceptions; see the passage above.  This obviously
>> needs to change if we're going to do anything useful with POSIX thread
>> cancellation.

> Not sure what "anything useful" means.

If all of the cancellation points are throw(), the cancellation exception
can't propagate, so we can't run any cleanups.  Which isn't very useful.

>> Both your and David's replies seem to have amounted to saying that any
>> change to current behavior is unacceptable.
>
> Not the way I understand the status quo.  As far as I can tell, what
> was described as the current compromise (termination) is unacceptable
> to me.  If I've misunderstood what you said I would be willing to
> revise my position.

To clarify, by "current behavior" I meant the C++ standard.

I certainly don't see the termination compromise as The Right Thing.  It's
just that in the previous discussion, we failed to reach agreement as to
what ought to happen when a catch(...) block doesn't rethrow a cancellation
exception.  Termination makes nobody happy, but it means that any eventual
resolution is a pure extension; nobody has written code that will break
when the semantics change.

>> And that we might have to adjust a few things to make that work?
>
> Yes.  The only things I think are crucial here is that functions which
> are specified not to throw (or conditions which are specified not to
> throw) continue to not throw anything, including cancellation, and
> that whatever guarantees functions give about program state in case
> they throw an exception also apply if the exception is a thread
> cancellation.  Almost without exception (NPI), code that works in the
> presence of exceptions does not depend on the meaning of said
> exceptions, so giving cancellation exceptions any kind of special
> license to violate assumptions made about other exceptions would be
> wrong.

I am sympathetic to this position.

>>> In the meantime, the ISO committee is discussing a standard threads
>>> library for C++, including a cancellation model incompatible with what
>>> is being proposed here.  It would be better for everybody involved for 
>>> Gcc to match it.
>>
>> Please elaborate.  I don't see a relevant paper in any of the recent
>> mailings.
>
> There ain't nothin'.  The effort to standardize Boost.Threads has been
> languishing :(

Well, can either of you give a brief sketch of the Boost.Threads
cancellation model?  Has David Butenhof been involved at all?  He seems to
have been thinking about the interaction of threads and exceptions longer
than anyone else.

Jason



More information about the Gcc mailing list