>>Spiros Bousbouras <spi...@gmail.comwrites:
[given appropriate definitions of a and env]
>>>a = setjmp(env); ... seems to violate [a non-"constraint" "shall"]
limits" of 7.13.1.1 of n869 so my guess is that it's not legal.
Indeed, code of this form uses undefined (at least undefined-
by-the-C-standards) behavior.
In article <11**********************@m36g2000hse.googlegroups .com>
Spiros Bousbouras <sp****@gmail.comwrote:
>I had read the relevant part of the rationale before posting
my question. What I'm looking for is a more concrete
explanation regarding the specific example I posted.
It is somewhat (or even "very" :-) ) difficult to come up with
a good example of how things go wrong here. What it boils down
to, in some sense, is a reluctance to force implementations to
recognize that "setjmp" is not a normal function.
On most machines, control flow tends to involve pushes and
pops onto a stack. This stack may or may not be shared with
that for arguments and/or function return values. When
evaluating complex expressions, this same stack may also be
used by the compiler for compiler-temporaries.
If the compiler believes that setjmp() is an ordinary function,
and therefore it has no "strange stack effects", the compiler
can interleave its own stack manipulations between those that
might occur for any ordinary function call. But if that same
stack is used for control flow, and setjmp() is "returned to"
by a later longjmp() so that control flow is abnormal, there
may be some sort of destructive interference between the two.
The same problem occurs with the (non-Standard) alloca()
function on machines like the x86. Since actual alloca()
implementations alter the stack, calls to alloca() must not
occur "between" operations that also alter the stack. Thus:
char *p;
size_t n;
...
p = alloca(n);
tends to work, but more complex operations like:
foo(p1 = alloca(n), bar(42), p2 = alloca(n), baz(p3 = alloca(n)));
tend to behave badly, because the compiler's stack adjustments
alter alloca()'s stack adjustments, so that p1, p2, and/or p3 may
point to the "wrong part" of the stack.
Simple assignments are likely to work even with "dumb" compilers
that implement setjmp() in the obvious, simple, way (without any
special-casing inside the compiler). More complex operations
like:
foo(setjmp(label1), 42, setjmp(label2));
are clearly asking for trouble. The fact is that setjmp() is like
a goto-label, and longjmp() actually goes to a setjmp() label, and
if a compiler recognizes these through special syntax -- in the
same way that any C99 compiler must now recognize the creation of
a variable-length array due to its special syntax[%] -- it can
arrange for the "right thing" to happen. A future Standard could
expand the list of "allowable setjmp situations" without really
harming anything, except perhaps compiler-writers' free time. :-)
[% Admittedly, VLA syntax looks like any other array definition.
The compiler can "see" that it is a VLA, though, because the
expression(s) that create the dimensions are not compile-time
constant-expressions. The Standard -- either one -- could have
done effectively the same thing with setjmp and longjmp by declaring
that they are keywords, or at least macros that expand to keywords,
even though they *look* like ordinary function calls. The
standards-folk simply chose not to do that.]
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it
http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.