jmp_buf
must be an array type for compatibility with existing practice:
programs typically omit the address operator before a jmp_buf argument,
even though a pointer to the argument is desired,
not the value of the argument itself.
Thus, a scalar or struct type is unsuitable.
Note that a one-element array of the appropriate type is a valid definition.
setjmp is constrained to be a macro only:
in some implementations the information necessary to restore context
is only available while executing the function making the call to
setjmp.
setjmp macro
One proposed requirement on setjmp
is that it be usable like any other function ---
that it be callable in any expression context,
and that the expression evaluate correctly whether the
return from setjmp
is direct or via a call to longjmp.
Unfortunately, any implementation of
setjmp as a conventional called
function cannot know enough about the calling environment to save any
temporary registers or dynamic stack locations
used part way through an expression evaluation.
(A setjmp macro seems to help only if it expands
to inline assembly code or a call to a special built-in
function.)
The temporaries may be correct on the initial call to setjmp,
but are not likely to be
on any return initiated by a corresponding call to longjmp.
These considerations dictated the constraint that setjmp
be called only from within fairly simple expressions,
ones not likely to need temporary storage.
An alternative proposal considered by the Committee
is to require that implementations recognize that calling
setjmp is a special case, [Footnote: This proposal was considered prior to the
adoption of the stricture that setjmp be a
macro. It can be considered as equivalent to
proposing that the setjmp macro expand to a
call to a special built-in compiler function.]
and hence that they take whatever precautions are necessary to restore the
setjmp environment properly upon a longjmp call.
This proposal was rejected on grounds of consistency:
implementations are currently
allowed to implement library functions specially,
but no other situations require special treatment.
longjmp function
The Committee also considered requiring that a call to longjmp
restore the (setjmp) calling environment fully ---
that upon execution of a longjmp,
all local variables in the environment of setjmp
have the values they did at the time of the longjmp call.
Register variables create problems with this idea.
Unfortunately, the best that many implementations attempt
with register variables is to save them (in jmp_buf)
at the time of the initial setjmp call,
then restore them to that state on each return initiated by a longjmp call.
Since compilers are certainly at liberty to change register variables
to automatic, it is not obvious that a register declaration will indeed
be rolled back.
And since compilers are at liberty to change automatic variables
to register (if their addresses are never taken),
it is not obvious that an automatic declaration will not be rolled back.
Hence the vague wording.
In fact, the only reliable way to ensure that a
local variable retain the value it had at the time of the call to
longjmp is to define it with the volatile attribute.
Some implementations leave a process in a special state while a signal
is being handled.
An explicit reassurance must be given to the environment when the signal
handler is done.
To keep this job manageable, the Committee agreed to restrict
longjmp to only one level of signal handling.
The longjmp function should not be called in an exit handler
(i.e., a function registered with the
atexit function (see §4.10.4.2)),
since it might jump to some code which is no longer in scope.