With the two C macro definitions
#define except_throw(x) goto x
#define except_catch(x) while (0) x:
"goto"s can be made to look good in C. (It turns out that Dijkstra was making a fashion statement all along.)
The first one simply works around "goto" having a bad name.
The second is used with a dangling statement or block, like "if":
except_catch (mem) return ERR_OUT_OF_MEMORY;
or
except_catch (hit) { printf("Ouch!\n"); damage++; }
It introduces a C statement or block that is only executed if it is entered via a jump. This lets a programmer move exception handling code away from the main algorithm, a structural benefit shared with "real", operating-system level exceptions. (Which of course are infinitely cooler if they work right, but require a lot of support.)
except_catch() statements can nest; multiple except_catch()'es inside one big one could be used to set an error variable to an error to the specific catch phrase, then continue with a generic cleanup.-- jutta, Aug 13 1999 Kazlib http://users.footpr...et/~kaz/kazlib.htmllibrary which implements clean exceptions in C. [johnmeacham, Mar 16 2002] I'd just like to reiterate that real exceptions are still preferable. The biggest practical limitation of these macros, as far as I can see, is that the exception handler must be compiled together with the code that raises the exception (or you'll get a "missing label" error at compile time). So you can't write a shared library that throws an exception on some error condition with the expectation that the caller will handle it in a manner appropriate to context. Still, it's a reasonable hack for people who want exception syntax in an exceptionless environment.-- baf, Apr 11 2000 I had UNWIND_PROTECT, CATCH, and THROW macros: CATCH(block) returns 0 for normal completion, or whatever THROW was passed if it was called.
UNWIND_PROTECT(block, cleanup_block) runs the block, then runs the cleanup block regardless of whether the block excepted, then passes the exception back up the stack if one happened.
UNWIND_PROTECT({ char *p=malloc(42); foo(p); }, { free(p);})-- reece, May 04 2000 Re: baf's objection: isn't the usual way to implement exception macros in C to use setjmp in the catch (or try) macro, and longjmp in the throw macro?-- brouhaha, Jun 15 2000 Re: setjmp/longjmp: Yes! (see, for example, van der Linden's "Expert C Programming").-- acooke, Aug 10 2000 I didn't know you could put a label there; how sneaky.
How would reece's postulated UNWIND_PROTECT etc. macros work?-- egnor, Apr 27 2001 This reminds me why I don't do C.-- phoenix, Mar 16 2002 random, halfbakery