Behaviour of setjmp/longjmp and registers
Chris Torek
chris at mimsy.UUCP
Thu Jan 26 01:36:06 AEST 1989
In article <7283 at polyslo.CalPoly.EDU> cquenel at polyslo.CalPoly.EDU
(96 more school days) writes:
>-- The real purpose of setjmp/longjmp is as a global goto
> when you have to go around the stack. It shouldn't
> need any "features" that make it easier to use. ...
>-- No semi-legitimate uses of setjmp/longjmp that come to mind
> actually would require the restoral of variables to function.
These are the key points (and, incidentally, tie in to the `B&D'
discussion in comp.lang.misc). For the sake of argument (which is
to say that I do not necessarily believe this myself), consider the
following use of setjmp/longjmp:
/* return type of signal functions, either int or void */
typedef void sigreturn_t;
static struct jbstack {
jmp_buf cur;
jmp_buf *prev;
} *jbstack;
sigreturn_t stop(int sig) {
longjmp(jbstack->cur, 1);
}
struct foo *timed_fiddle_with(struct foo *base) {
int fd;
sigreturn_t (*oldalarm)();
struct jbstack j;
j.prev = jbstack;
jbstack = &j;
if (setjmp(&j.cur)) {
/* timeout */
jbstack = j.prev;
(void) signal(SIGALRM, oldalarm);
free((void *)base);
return NULL;
}
(void) alarm(base->timeout);
oldalarm = signal(SIGALARM, stop);
fd = open(base->name, base->mode);
(void) alarm(0);
base->fd = fd;
jbstack = j.prev;
return base;
}
(longjmp is required wherever signals do not interrupt system calls.)
This is really the beginning of a general exception mechanism with
protection against stack unwinding, so that routines can clean up
after themselves if interrupted (even if the interruption leaps
from a low-level routine all the way back to main()).
It can be argued that implementing such an exception mechanism using
longjmp is a reasonable thing. Indeed, a number of languages provide
more direct methods (e.g., Mesa and various Lisps); C provides
sufficient primitives, leaving the discipline to use them to the
programmer.
Now, clearly one can sprinkle `volatile' qualifiers into the
declarations in timed_fiddle_with(), so that it will work under pANS
C. But (at least some of) the variables so declared are not in fact
volatile---the value of `base', in particular, *never changes!* The
qualifier is being (mis)used strictly for its side effect of inhibiting
optimisation, not because the variable that is so qualified behaves in
a way that is not described by the virtual machine.
--
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain: chris at mimsy.umd.edu Path: uunet!mimsy!chris
More information about the Comp.lang.c
mailing list