Is this a legal way to use setjmp ?

Discussion in 'C Programming' started by Spiros Bousbouras, Jun 21, 2007.

  1. 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 ?
     
    Spiros Bousbouras, Jun 21, 2007
    #1
    1. Advertising

  2. Spiros Bousbouras

    Ben Pfaff Guest

    Spiros Bousbouras <> 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
     
    Ben Pfaff, Jun 21, 2007
    #2
    1. Advertising

  3. On 21 Jun, 07:06, Ben Pfaff <> wrote:
    > Spiros Bousbouras <> 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.
     
    Spiros Bousbouras, Jun 21, 2007
    #3
  4. On 21 Jun, 07:06, Ben Pfaff <> wrote:
    > Spiros Bousbouras <> 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 ?
     
    Spiros Bousbouras, Jun 21, 2007
    #4
  5. In article <>,
    Spiros Bousbouras <> 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.
     
    Richard Tobin, Jun 21, 2007
    #5
  6. Spiros Bousbouras

    Chris Torek Guest

    >>Spiros Bousbouras <> 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 <>
    Spiros Bousbouras <> 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.
     
    Chris Torek, Jun 23, 2007
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Thomas Baruchel

    How dirty is setjmp+fopen+longjmp ?

    Thomas Baruchel, Oct 2, 2003, in forum: C Programming
    Replies:
    2
    Views:
    470
    Eric Sosman
    Oct 2, 2003
  2. Mantorok Redgormor

    setjmp, longjmp

    Mantorok Redgormor, Nov 12, 2003, in forum: C Programming
    Replies:
    2
    Views:
    448
    Ian Woods
    Nov 12, 2003
  3. someone
    Replies:
    5
    Views:
    3,529
    SM Ryan
    May 1, 2004
  4. Michael B Allen

    Is setjmp/longjmp ok?

    Michael B Allen, May 1, 2004, in forum: C Programming
    Replies:
    11
    Views:
    2,287
    -wombat-
    May 4, 2004
  5. Player

    Is this setjmp/jongjmp usable legal?

    Player, Jan 3, 2013, in forum: C Programming
    Replies:
    23
    Views:
    524
    Tim Rentsch
    Jan 7, 2013
Loading...

Share This Page