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