h a l f b a k e r yFlaky rehab
add, search, annotate, link, view, overview, recent, by name, random
news, help, about, links, report a problem
browse anonymously,
or get an account
and write.
register,
|
|
|
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.
Kazlib
http://users.footpr...et/~kaz/kazlib.html library which implements clean exceptions in C. [johnmeacham, Mar 16 2002]
[link]
|
|
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. |
|
|
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);}) |
|
|
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? |
|
|
Re: setjmp/longjmp: Yes! (see, for example, van der Linden's "Expert C Programming"). |
|
|
I didn't know you could put a label there; how sneaky. |
|
|
How would reece's postulated UNWIND_PROTECT etc. macros work? |
|
|
This reminds me why I don't do C. |
|
| |