Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: Notesfiles $Revision: 1.6.2.16 $; site ada-uts.UUCP Path: utzoo!watmath!clyde!burl!ulysses!allegra!mit-eddie!think!ada-uts!richw From: richw@ada-uts.UUCP Newsgroups: net.lang.c Subject: Exception Handling? Impossible! Message-ID: <10200002@ada-uts.UUCP> Date: Mon, 12-Aug-85 15:03:00 EDT Article-I.D.: ada-uts.10200002 Posted: Mon Aug 12 15:03:00 1985 Date-Received: Sun, 18-Aug-85 01:41:47 EDT Lines: 121 Nf-ID: #N:ada-uts:10200002:000:3256 Nf-From: ada-uts!richw Aug 12 15:03:00 1985 EXCEPTION HANDLING ??!? The following includes "files" of macros and a simple modification of the "exit" routine which allows one to do pseudo-exception-handling in C. An example of their use is provided in the "test.c" file. There are problems with these macros (and the modified "exit"), I admit. The purpose of this note is to get feedback on possible solutions to some of the problems. I'd also like INTELLIGENT comments about what's going on (please refrain from verborrhea like "How could you name the macro 'except_when'?! Name it 'if_exception'!" ). Problems I can see right off: 1) The raise macro must still use a return statement (which is why I've provided raise_return, for those cases where garbage results are inappropriate). 2) Arbitrary statements may be executed between the call to the procedure that raised an exception and the handler. 3) Unhandled exceptions come to the attention of the user only when another "raise" is attempted or when the program terminates. 4) The raise macro includes a return statement since most exceptions (at least in programs that I write) are used to signal alternate termination conditions of a procedure. This implies that "local" exceptions can't be raised (e.g. to jump out of nested loops). 5) An "exception" is simply a string. It's "declaration" requires (?) some redundancy (i.e. the variable name and the string literal will usually look the same). -- Rich Wagner ------------------------- test.c ------------------------------- #include "exceptions.h" #includeException overflow = "Overflow"; raiser(b) int b; { fprintf(stderr, "Raiser called with %d\n", b); if (b) raise(overflow); fprintf(stderr, "Leaving raiser\n\n"); } main() { raiser(0); except_when(overflow) fprintf(stderr, "Caught when it wasn't raised\n"); end_except; raiser(1); except_when(overflow) fprintf(stderr, "Caught\n"); end_except; raiser(0); raiser(1); raiser(1); fprintf(stderr, "Last line of main\n"); } ------------------------ test output ---------------------------- Raiser called with 0 Leaving raiser Raiser called with 1 Caught Raiser called with 0 Leaving raiser Raiser called with 1 Raiser called with 1 Unhandled exception: Overflow ------------------------ exceptions.h --------------------------- extern int _xxraised; extern char *_xxexc; #define raise(e) { if (_xxraised) exit(1);\ _xxexc = e; _xxraised = 1; return; } #define raise_return(e,r) { if (_xxraised) exit(1);\ _xxexc = e; _xxraised = 1 ; return r; } #define except_when(e) if (_xxraised) {\ if (_xxexc == (e)) { _xxraised = 0; #define when(e) } else if (_xxexc == (e)) { _xxraised = 0; #define end_except } else exit(1); } typedef char *Exception; ------------------------ exceptions.c ----------------------------- #include int _xxraised = 0; char *_xxexc; exit(status) int status; { if (_xxraised) { fprintf(stderr, "Unhandled exception: %s\n", _xxexc); _xxexit(status ? status : 1); } _xxexit(status); /* _xxexit is the old "exit" we all know and love, */ /* just renamed. */ }