![]() |
Is this a legal way to use setjmp ?
In the following assume that a is int and
env is of type jmp_buf a = setjmp(env) ; Is it legal ? It looks reasonable but it seems to violate what is mentioned under "Environmental limits" of 7.13.1.1 of n869 so my guess is that it's not legal. If it's not legal could someone give me some insight on why making this behave correctly would present difficult problems for an implementation ? |
Re: Is this a legal way to use setjmp ?
Spiros Bousbouras <spibou@gmail.com> writes:
> In the following assume that a is int and > env is of type jmp_buf > a = setjmp(env) ; > Is it legal ? It looks reasonable but it seems to > violate what is mentioned under "Environmental > limits" of 7.13.1.1 of n869 so my guess is that > it's not legal. No. > If it's not legal could someone give me some insight > on why making this behave correctly would present > difficult problems for an implementation ? The C99 rationale has this to say: 7.13.1.1 The setjmp macro 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. One proposed requirement on setjmp is that it be usable like any other function, that is, 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 C89 Committee was to require that implementations recognize that calling setjmp is a special case7, 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. -- Comp-sci PhD expected before end of 2007 Seeking industrial or academic position *outside California* in 2008 |
Re: Is this a legal way to use setjmp ?
On 21 Jun, 07:06, Ben Pfaff <b...@cs.stanford.edu> wrote:
> Spiros Bousbouras <spi...@gmail.com> writes: > > In the following assume that a is int and > > env is of type jmp_buf > > a = setjmp(env) ; > > Is it legal ? It looks reasonable but it seems to > > violate what is mentioned under "Environmental > > limits" of 7.13.1.1 of n869 so my guess is that > > it's not legal. > > No. > > > If it's not legal could someone give me some insight > > on why making this behave correctly would present > > difficult problems for an implementation ? > > The C99 rationale has this to say: <snip> 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. |
Re: Is this a legal way to use setjmp ?
On 21 Jun, 07:06, Ben Pfaff <b...@cs.stanford.edu> wrote:
> Spiros Bousbouras <spi...@gmail.com> writes: > > In the following assume that a is int and > > env is of type jmp_buf > > a = setjmp(env) ; > > Is it legal ? It looks reasonable but it seems to > > violate what is mentioned under "Environmental > > limits" of 7.13.1.1 of n869 so my guess is that > > it's not legal. > > No. > > > If it's not legal could someone give me some insight > > on why making this behave correctly would present > > difficult problems for an implementation ? > > The C99 rationale has this to say: > > 7.13.1.1 The setjmp macro < partial snip> > An alternative proposal considered by the C89 Committee was > to require that implementations recognize that calling setjmp > is a special case7, 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. It occurs to me that not allowing something as basic as a = setjmp(env) ; is not very consistent either. Are there other examples of functions or macros where you cannot do that ? |
Re: Is this a legal way to use setjmp ?
In article <1182403863.096803.121570@k79g2000hse.googlegroups .com>,
Spiros Bousbouras <spibou@gmail.com> wrote: >In the following assume that a is int and >env is of type jmp_buf >a = setjmp(env) ; > >Is it legal ? It looks reasonable but it seems to >violate what is mentioned under "Environmental >limits" of 7.13.1.1 of n869 so my guess is that >it's not legal. > >If it's not legal could someone give me some insight >on why making this behave correctly would present >difficult problems for an implementation ? When longjmp() is called control will return to the calling function in the middle of the expression a=setjmp(env). In general, that expression might use arbitrary temporary registers, but if setjmp() is an ordinary function it will not be able to determine which registers those are. I don't find this entirely convincing - setjmp() could just save all the registers used as temporaries, and if that's too expensive then you don't *have* to implement it as an ordinary function, and in any case how many unknown temporaries are going to be used in a simple assignment? - but then I've never written a C compiler. Perhaps there were existing implementations that couldn't handle it. No-one designing a new language would expect to be able to implement something like setjmp() as a plain function. -- Richartd -- "Consideration shall be given to the need for as many as 32 characters in some alphabets" - X3.4, 1963. |
Re: Is this a legal way to use setjmp ?
>>Spiros Bousbouras <spi...@gmail.com> writes:
[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 <1182406430.170351.219180@m36g2000hse.googlegroups .com> Spiros Bousbouras <spibou@gmail.com> wrote: >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. |
| All times are GMT. The time now is 12:50 AM. |
Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.