Article View: comp.std.c
Article #4795Re: setjmp usage question
From: walter briscoe
Date: Sun, 25 Feb 1996 12:16
Date: Sun, 25 Feb 1996 12:16
107 lines
5668 bytes
5668 bytes
In article <4gnusq$7be@senator-bedfellow.MIT.EDU>
tada@athena.mit.edu "Michael J Zehr" writes:
>
> I'm trying to determine whether a particular usage of setjmp is
> sanctioned by the standard and I'm finding a compiler bug or whether my
> usage is non-conforming. My code boils down to this:
>
[code assigns the result of setjmp to a variable]
> Should this code work correctly? In particular, can a compiler
> increment env_index after longjmp is called?
>
> [Additional question because I'm curious: what happens to
> post-increments that are in parameters of the longjmp call? Are they
> ever executed? I suppose the general question is where are the sequence
> points when you're using setjmp and lonjmp?]
I made a similar mistake some time ago when using an implementation
which did not document the restrictions of setjmp/longjmp and which
behaved inconsistently when run with/without a debugger. setjmp and
longjmp should be used very carefully when no reasonable alternative
exists. They seem to be really difficult for many implementors. Signal
handling is the one thing that is even more difficult and for which
portable usage is very difficult indeed. Anyway, enough dire warnings.
ANSI/ISO 9899-1990 "7.6 Nonlocal jumps <setjmp.h>" contains:
> It is unspecified whether setjmp is a macro or an identifier declared
> with external linkage. If a macro definition is suppressed in order to
> access an actual function, or a program defines an external identifier
> with the name setjmp, the behavior is undefined.
So, you are ill-advised to do "#undef setjmp" or "(setjmp)(env)".
> Environmental constraint
>
> An invocation of the setjmp macro shall appear only in one of the
> following contexts:
>
> - the entire controlling expression of a selection or iteration
> statement;
>
> - one operand of a relational or equality operator with the other
> operand an integral constant expression, with the resulting expression
> being the entire controlling expression of a selection or iteration
> statement;
>
> - the operand of a unary ! operator with the resulting expression being
> the entire controlling expression of a selection or iteration statement;
> or
>
> - the entire expression of an expression statement (possibly cast to
> void).
This highly restrictive list does not include assigning the result!
[snip]
> The longjmp function restores the environment saved by the most recent
> invocation of the setjmp macro in the same invocation of the program,
> with the corresponding jmp_buf argument. If there has been no such
> invocation, or if the function containing the invocation of the setjmp
> macro has terminated execution in the interim, the behavior is undefined.
>
> All accessible objects have values as of the time longjmp was called,
> except that the values of objects of automatic storage duration that are
> local to the function containing the invocation of the corresponding
> setjmp macro that do not have volatile-qualified type and have been
> changed between the setjmp invocation and longjmp call are indeterminate.
>
> As it bypasses the usual function call and return mechanisms, the
> longjmp function shall execute correctly in contexts of interrupts,
> signals and any of their associated functions. However, if the longjmp
> function is invoked from a nested signal handler (that is, from a
> function invoked as a result of a signal raised during the handling of
> another signal), the behavior is undefined.
I had problems with my last usage of setjmp/longjmp in a lex analyser.
My first reaction was to eliminate the technique. Unfortunately, there
was a failure in re-initialisation code I had written but the point
remains: this is a powerful, dangerous technique.
A cruel and unusual test of an implementation would be to do a longjmp
or raise a signal from a callback routine passed to bsearch or qsort.
With luck, following calls of bsearch or qsort would break! If I had an
implementor's hat on, I would argue that that is undefined behavior
because the callback routine is mandated to return. As a user, I would
argue that the consequence of a failure to comply with "shall" is not
specified in the standard and that, while failure of the running
function is required by the user action, the consequential failure was
unreasonable. Comments please from the language lawyers.
IMHO, bsearch and qsort are functions which have received insufficient
publicity. Searching and sorting algorithms are difficult to test and,
for most applications, timing is not critical. For dealing with data
which can be modelled as an array whose logical size is known at run
time, they form a useful technique. If the key of the array starts at
the beginning of each entry and consists of a fixed number of
characters, the comparison functions memcmp, strcmp, and strncmp even
allow one to call the searc functions without having to write any
auxiliary code.
I apologise to the group for digression from the original topic and
express thanks to Michael J Zehr for stimulating the thought.
--
walter briscoe
Technical Details
Message-ID:
<825250570snz@wbriscoe.demon.co.uk>Path:
arc1-ca.pugleaf.net!mail2news.demon.co.uk!wbriscoe.demon.co.ukReferences:
<4gnusq$7be@senator-bedfellow.MIT.EDU>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!mail2news.demon.co.uk!wbriscoe.demon.co.uk From: walter briscoe <walter@wbriscoe.demon.co.uk> Newsgroups: comp.std.c Subject: Re: setjmp usage question Date: Sun, 25 Feb 96 12:16:10 GMT Message-ID: <825250570snz@wbriscoe.demon.co.uk> References: <4gnusq$7be@senator-bedfellow.MIT.EDU> Reply-To: walter@wbriscoe.demon.co.uk X-NNTP-Posting-Host: wbriscoe.demon.co.uk X-Newsreader: Demon Internet Simple News v1.30 X-Mail2News-Path: wbriscoe.demon.co.uk