Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #15209

Re: Exception propagation in C

From Kaz Kylheku <kaz@kylheku.com>
Newsgroups comp.lang.c, alt.os.development
Subject Re: Exception propagation in C
Date 2011-12-29 21:02 +0000
Organization A noiseless patient Spider
Message-ID <20111229115726.384@kylheku.com> (permalink)
References <99fbedd4-b37f-4ced-8759-4ba9656259dc@m7g2000vbc.googlegroups.com>

Cross-posted to 2 groups.

Show all headers | View raw


On 2011-12-29, James Harris <james.harris.1@googlemail.com> wrote:
> Below is a suggestion for handling - more accurately, propagating -
> exceptions in C. It is intended for overall program performance though
> it goes against a preference of many including me. Can anyone come up
> with a faster or better way to propagate exceptions? What other ways
> are there to handle exceptions in C? What do you do? (I tend to detect
> exceptions where they occur by checking return values but I have never
> had a good way in C to get them to propagate.)
>
> The issue is the desire to have exception propagation using *standard*
> C. I'm not talking principally about detecting exceptions but of a way
> for nested functions to signal an exception and have that exception
> propagate back along the call chain to a function that is set up to
> handle it.
>
> * Option 1. Use setjmp/longjmp. Not too good as, to be compatible,
> they need to be used in an if or a switch statement IIRC which can be
> inconvenient. Don't they also need a separate jump buffer for each
> active setjmp? I have used them in the past but found them awkward.
>
> * Option 2. Traditional exception handling. As used in other languages
> this unwinds the stack of function calls looking for a handler. I
> cannot think of a way to implement that in C.

Option 2 can be done using Option 1, with some macros.

It can be be done and I have done it, as well as others. Years ago I wrote an
exception handling module that came to be used in Ethereal (now called
Wireshark) which is written in C. Maybe that code is still used.  If a packet
is captured by Wireshark which is truncated (does not parse properly according
to its protocol) the packet dissectors throw an exception.

More recently, I made setjmp-based exception handling in a language
called TXR, more sophisticated than that old one.

See here:

http://www.kylheku.com/cgit/txr/tree/unwind.c
http://www.kylheku.com/cgit/txr/tree/unwind.h

This can't be easily lifted into other C programs, though, because
of the reliance on the "val" type, which is a dynamically typed value.

> the need to push and pop sufficient context
> for the exception handler to recognise where a given exception should
> be caught, 2) the consequent loss of sync between the stack and the
> CPU's branch prediction for returns.

Any exception handling that isn't integrated into your compiler is going to be
slow in some way compared to a "state of the art" implementation that is
properly integrated into a language. That is almost a given.

> * Option 3. The function detecting an exception creates an exception
> object and sets an exception type in a thread-specific variable. Any
> calling functions, after each call (or group of calls) test that
> variable.

Testing a global error status variable is not exception handling,
even if you call that variable "current_exception" or whatever
gives you a feeling that the approach is "exceptional".

Exception handling was invented specifically to avoid crufty
code like this.

It becomes an exception handling strategy if you can hide those tests from the
programmer (i.e. have the compiler generate them).

> If non-zero they jump to a local exception handler if there
> is one or jump to a return from the current function if not. This does
> involve a test and branch for each call but that is very fast (fusible
> and single cycle) and it avoids the need for exception handling
> context to be pushed and popped. It would also preserve the branch
> prediction of calls and returns.

But, at least, functions which are not interested in exception handling do not
have to push and pop contexts (unless they have local resources that need
unwinding!) 

Under Option 3, all functions have to cooperate, because any normal return is
suspected of occuring in an exceptional situation. If an exceptional return is
happening, then subsequent statements in a function must not be executed. Every
function must check and return.

This is likely going to be a loser in the average cases, not to mention a
nightmare to maintain.

Furthermore, your scheme won't work when the call stack contains frames from
third-party libraries, even if those libraries don't have any local resources
that need cleanup.  Longjmp-based exceptions can work through third party call
frames when those frames have no local resources that must be cleaned up.

In any good exception handling implementation, functions that are not involved
with exception handling or unwinding do not "pay" any cost. 

The tradeoff is played out between the cost of searching for the exit point
and doing the control transfer, and the cost of setting up a catch or unwind
handler.

In general, if you make it very cheap to set up the catch, then the machine has
to work harder in processing a throw, to identify where to go and to restore
the state properly.

> There are subtleties but option 3 is the basic idea. Anyone know of
> something better?

I can't think of anything that isn't better. 

Oh, here is one: it's not worse than a big hammer on a spring popping out of
your computer's case and whacking you on the head when an error occurs!

The really silly thing is that you're worried about shaving machine cycles on
comparisons or branch prediction, but you're overlooking what it costs to do a
thread-local lookup, which this scheme requires at every function call
boundary, just in case an exception is happening.

(You can pass the address of that variable as an extra argument among your
functions wherever that is feasible, I suppose: yet more cruft.)

Back to comp.lang.c | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread


Thread

Exception propagation in C James Harris <james.harris.1@googlemail.com> - 2011-12-29 09:52 -0800
  Re: Exception propagation in C jacob navia <jacob@spamsink.net> - 2011-12-29 19:40 +0100
    Re: Exception propagation in C BGB <cr88192@hotmail.com> - 2011-12-29 14:03 -0600
  Re: Exception propagation in C BGB <cr88192@hotmail.com> - 2011-12-29 13:07 -0600
    Re: Exception propagation in C James Harris <james.harris.1@googlemail.com> - 2011-12-30 13:38 -0800
      Re: Exception propagation in C BGB <cr88192@hotmail.com> - 2011-12-30 20:24 -0600
        Re: Exception propagation in C James Harris <james.harris.1@googlemail.com> - 2012-01-03 02:19 -0800
          Re: Exception propagation in C BGB <cr88192@hotmail.com> - 2012-01-03 14:04 -0600
            Re: Exception propagation in C James Harris <james.harris.1@googlemail.com> - 2012-01-04 04:26 -0800
              Re: Exception propagation in C BGB <cr88192@hotmail.com> - 2012-01-06 14:05 -0600
                Re: Exception propagation in C jacob navia <jacob@spamsink.net> - 2012-01-06 23:54 +0100
                Re: Exception propagation in C "Ed Coran" <sysdev@new.net> - 2012-01-06 22:24 -0600
                Re: Exception propagation in C jacob navia <jacob@spamsink.net> - 2012-01-07 09:15 +0100
                Re: Exception propagation in C "Ed Coran" <sysdev@new.net> - 2012-01-08 23:45 -0600
                Re: Exception propagation in C James Harris <james.harris.1@googlemail.com> - 2012-01-08 12:52 -0800
                Re: Exception propagation in C James Harris <james.harris.1@googlemail.com> - 2012-01-08 14:20 -0800
                Re: Exception propagation in C jacob navia <jacob@spamsink.net> - 2012-01-09 00:19 +0100
                Re: Exception propagation in C James Harris <james.harris.1@googlemail.com> - 2012-01-08 21:12 -0800
                Re: Exception propagation in C Scott Wood <scott@buserror.net> - 2012-01-08 23:41 -0600
                Re: Exception propagation in C James Harris <james.harris.1@googlemail.com> - 2012-01-09 11:00 -0800
                Re: Exception propagation in C Scott Wood <scott@buserror.net> - 2012-01-10 00:42 -0600
                Re: Exception propagation in C jgk@panix.com (Joe keane) - 2012-01-11 07:40 +0000
                Re: Exception propagation in C James Harris <james.harris.1@googlemail.com> - 2012-01-11 12:59 -0800
                Re: Exception propagation in C "Ed Coran" <sysdev@new.net> - 2012-01-09 00:05 -0600
                Re: Exception propagation in C Ian Collins <ian-news@hotmail.com> - 2012-01-09 20:40 +1300
                Re: Exception propagation in C "Ed Coran" <sysdev@new.net> - 2012-01-09 04:53 -0600
                Re: Exception propagation in C 88888 Dihedral <dihedral88888@googlemail.com> - 2012-01-09 05:49 -0800
                Re: Exception propagation in C Scott Wood <scott@buserror.net> - 2012-01-08 17:29 -0600
                Re: Exception propagation in C jacob navia <jacob@spamsink.net> - 2012-01-09 00:37 +0100
                Re: Exception propagation in C Nomen Nescio <nobody@dizum.com> - 2012-01-09 11:36 +0100
                Re: Exception propagation in C James Harris <james.harris.1@googlemail.com> - 2012-01-09 11:08 -0800
          Re: Exception propagation in C Scott Wood <scott@buserror.net> - 2012-01-05 01:25 -0600
            Re: Exception propagation in C James Harris <james.harris.1@googlemail.com> - 2012-01-05 09:18 -0800
      Re: Exception propagation in C "s_dubrovich@yahoo.com" <s_dubrovich@yahoo.com> - 2011-12-30 21:20 -0800
        Re: Exception propagation in C "Rod Pemberton" <do_not_have@noavailemail.cmm> - 2011-12-31 06:19 -0500
        Re: Exception propagation in C Nick Keighley <nick_keighley_nospam@hotmail.com> - 2012-01-01 10:32 -0800
      Re: Exception propagation in C "Rod Pemberton" <do_not_have@noavailemail.cmm> - 2011-12-31 05:53 -0500
        Re: Exception propagation in C James Harris <james.harris.1@googlemail.com> - 2012-01-01 16:30 -0800
          Re: Exception propagation in C "Rod Pemberton" <do_not_have@noavailemail.cmm> - 2012-01-02 01:50 -0500
            Re: Exception propagation in C Scott Wood <scott@buserror.net> - 2012-01-02 02:03 -0600
              Re: Exception propagation in C "Rod Pemberton" <do_not_have@noavailemail.cmm> - 2012-01-02 15:59 -0500
                Re: Exception propagation in C James Harris <james.harris.1@googlemail.com> - 2012-01-03 04:12 -0800
                Re: Exception propagation in C Scott Wood <scott@buserror.net> - 2012-01-04 23:53 -0600
                Re: Exception propagation in C "Rod Pemberton" <do_not_have@noavailemail.cmm> - 2012-01-05 06:45 -0500
            Re: Exception propagation in C James Harris <james.harris.1@googlemail.com> - 2012-01-03 04:16 -0800
              Re: Exception propagation in C Keith Thompson <kst-u@mib.org> - 2012-01-03 11:50 -0800
      Re: Exception propagation in C Jens Gustedt <jens.gustedt@loria.fr> - 2011-12-31 13:40 +0100
        Re: Exception propagation in C BGB <cr88192@hotmail.com> - 2011-12-31 10:40 -0600
          Re: Exception propagation in C Jens Gustedt <jens.gustedt@loria.fr> - 2012-01-02 16:49 +0100
            Re: Exception propagation in C BGB <cr88192@hotmail.com> - 2012-01-02 13:02 -0600
              Re: Exception propagation in C Dr Nick <3-nospam@temporary-address.org.uk> - 2012-01-02 19:53 +0000
                Re: Exception propagation in C ImpalerCore <jadill33@gmail.com> - 2012-01-02 13:10 -0800
              Re: Exception propagation in C ImpalerCore <jadill33@gmail.com> - 2012-01-02 12:58 -0800
              Re: Exception propagation in C Jens Gustedt <jens.gustedt@loria.fr> - 2012-01-04 18:01 +0100
                Re: Exception propagation in C BGB <cr88192@hotmail.com> - 2012-01-06 14:38 -0600
                Re: Exception propagation in C "Rod Pemberton" <do_not_have@noavailemail.cmm> - 2012-01-06 21:40 -0500
  Re: Exception propagation in C Kaz Kylheku <kaz@kylheku.com> - 2011-12-29 21:02 +0000
    Re: Exception propagation in C jacob navia <jacob@spamsink.net> - 2011-12-30 10:38 +0100
    Re: Exception propagation in C James Harris <james.harris.1@googlemail.com> - 2011-12-30 14:38 -0800
  Re: Exception propagation in C "Rod Pemberton" <do_not_have@noavailemail.cmm> - 2011-12-29 18:37 -0500
  Re: Exception propagation in C "BartC" <bc@freeuk.com> - 2011-12-30 01:07 +0000
    Re: Exception propagation in C James Harris <james.harris.1@googlemail.com> - 2011-12-30 14:07 -0800
  Re: Exception propagation in C Eric Sosman <esosman@ieee-dot-org.invalid> - 2011-12-30 17:53 -0500
    Re: Exception propagation in C James Harris <james.harris.1@googlemail.com> - 2012-01-03 03:56 -0800
  Re: Exception propagation in C jgk@panix.com (Joe keane) - 2012-01-02 09:49 +0000
    Re: Exception propagation in C Kleuske <kleuske@nowhere.net> - 2012-01-02 10:51 +0000
      Re: Exception propagation in C "Rod Pemberton" <do_not_have@noavailemail.cmm> - 2012-01-02 16:01 -0500
        Re: Exception propagation in C Kleuske <kleuske@nowhere.net> - 2012-01-03 11:14 +0000
      Re: Exception propagation in C James Harris <james.harris.1@googlemail.com> - 2012-01-03 03:59 -0800
        Re: Exception propagation in C Kleuske <kleuske@nowhere.net> - 2012-01-03 12:09 +0000
  Re: Exception propagation in C jgk@panix.com (Joe keane) - 2012-01-03 21:25 +0000
    Re: Exception propagation in C James Harris <james.harris.1@googlemail.com> - 2012-02-15 14:24 -0800
      Re: Exception propagation in C jgk@panix.com (Joe keane) - 2012-02-17 22:38 +0000

csiph-web