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>
