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.