This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [basic-improvements] try/finally support for c/c++ - more tests


On Wed, 6 Nov 2002, Mark Mitchell wrote:

> > #define pthread_cleanup_push(routine_, arg_) \
> >   __builtin_cleanup_block(routine_, arg_) {
> >
> > #define pthread_cleanup_pop(doit_) \
> >   __builtin_toggle_do_cleanup(doit_); }
> Something like this is a much, much closer to what I think we should
> do.
> Thanks for working this through.

Uhh, that's exceedingly ugly.  Try to think of the proposed semantic and
then try to come up with syntax implementing that semantic.  The special
property of this extension is, that it changes control flow in a very
non-trivial (but well defined) way.  Every control flow related construct
in C (except calls) are done by "top-level" keywords and syntactic
structure (if, while, for, goto ...).  Therefore I'm totally and strictly
against implementing cleanups with the help of builtins, which have
function-call like syntax.

Now let's look at the wanted semantic of cleanups: "Do something (A), and
if A is done, no matter what, do B".  This means, we at least have the
notion of two different statement sets, i.e. two blocks.  Then we need at
least one syntactic element to bind them together and give them that
semantic.  A keyword is the natural choice.  The best choice of the
placement of that keyword seems to be in front of the whole construct.
That leads to:

  { A }
  { B }

This is esthetically unpleasant, because now it isn't very easy to see,
that both blocks belong to the same construct, and are on the same level,
i.e. it could be confused (structure-wise) with 'if (...) { A }  { B }'.
Therefore we do a similar thing like in if-else (it's not
"if-else (...)  { A }  { B }" for a reason), which leads to

  { A }
  { B }

Now you only need to choose how to call both keywords, and __finally seems
to be good enough for the second.  __try for the first is not optimal,
because we not only "try" A, but really do it completely, but looking at
other compilers having such constructs and C++ exception handling, it also
isn't the worst choice.

That some people here consider the lack of ability to pass around
exception objects to be a deficiency stems from the fact, that sometimes
in this thread exception handling and cleanups were confused.  The
proposed language extension has next to nothing to do with exceptions, but
just with cleanups.  That cleanups can happen while unwinding the stack
for throwing an exceptions is the only connection.

Regarding semantic again: block A shall only be entered by fall-through
from the syntactically preceding statements, and shall be left only by
return, break, fallthrough, goto to label (_not_ computed), by throwing
an exception (maybe from a called function) or by exiting the program (in
which case the cleanup needs not to be run).  The same for B, except the
language about the cleanup.

I'm of course not sure, but I can't think of many variations how to
design cleanups, ergo I think if ISO C once includes it, it will be very
similar to what we would have now.

I really think, that this is one of the more well-designed and
unproblematic extensions.  And contrary to some people here I don't even
think it's such a invasive language change at all.  It's quite orthogonal
to the rest of the language by introducing a new toplevel construct.
Contrary to statement expressions for instance.

If people have problems with this extension they should name them so they
can be fixed, instead of just being "sceptic" or "nervous", or generally
just against it until some standard standardizes it (which by the way is
anyway the wrong direction.  Standards fixate existing practice, they
don't establish it.)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]