Date: Wed, 3 Nov 1999 18:10:18 -0800 (PST) From: Archie Cobbs <archie@whistle.com> To: freebsd-java@freebsd.org Subject: try { } catch { } finally { } in C! Message-ID: <199911040210.SAA82085@bubba.whistle.com>
next in thread | raw e-mail | index | archive | help
Did you know that try { } catch { } finally { } is possible from C? Well, GNU C anyway.. Example (using the header file included below): #include <stdlib.h> #include <stdio.h> #include <time.h> #include <assert.h> #include <setjmp.h> #include "trycatch.h" int func() { int r = (int)random() % 32; if (r > 16) { printf("func() throwing %d\n", 7); THROW(7); } printf("func() returning %d\n", r); return r; } int main() { int r = 123; srandom(time(NULL)); TRY { int y; printf("main() try #1\n"); printf("main() calling func()\n"); y = func(); printf("func() returned %d\n", r); y = (int)random() % 32; if (y > 20) { printf("main() throwing %d\n", -y); THROW(-y); } printf("main() end of try part\n"); printf("main() RETURN()'ing %d\n", r); RETURN(r); } CATCH(int, x) { printf("main() start of catch, x=%d\n", x); } FINALLY { printf("main() start of finally, r=%d\n", r); } ENDTRY; printf("main() returning\n"); return(0); } -Archie ___________________________________________________________________________ Archie Cobbs * Whistle Communications, Inc. * http://www.whistle.com /* This is a per-thread global variable */ jmp_buf _tryJmpBuf; /* This precedes the TRY block */ #define TRY { \ __label__ _finallyLabel; \ volatile jmp_buf _tryJmpBufSave; \ void *_finallyReturn = NULL; \ int _thrownValue; \ \ memcpy((void *)&_tryJmpBufSave, \ _tryJmpBuf, sizeof(jmp_buf)); \ if ((_thrownValue = setjmp(_tryJmpBuf)) == 0) /* This precedes the CATCH block */ #define CATCH(type, var) \ else { \ type var = (type) _thrownValue; \ \ memcpy(&_tryJmpBuf, (void *)&_tryJmpBufSave, \ sizeof(jmp_buf)); \ if ((_thrownValue = setjmp(_tryJmpBuf)) == 0) { /* Use this instead of CATCH() when you don't want to catch anything */ #define NOCATCH() { \ if (0) { /* This precedes the FINALLY block */ #define FINALLY } else { \ memcpy(&_tryJmpBuf, (void *)&_tryJmpBufSave,\ sizeof(jmp_buf)); \ } \ } \ (void)&&_finallyLabel; /* avoid gcc warning */ \ _finallyLabel: /* This is requried after the FINALLY block */ #define ENDTRY if (_thrownValue != 0) \ THROW(_thrownValue); \ if (_finallyReturn != NULL) \ goto *_finallyReturn; \ } /* Throw an exception 't' which must be castable to type int */ #define THROW(t) do { \ int value = (int) t; \ assert(value != 0); \ longjmp(_tryJmpBuf, value); \ } while (0) /* For use only within TRY or CATCH blocks (not FINALLY) */ #define RETURN(x...) do { \ __label__ _returnLabel; \ _finallyReturn = &&_returnLabel; \ goto _finallyLabel; \ _returnLabel: \ return x; \ } while (0) To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-java" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199911040210.SAA82085>