4

The C Reference Manual, Appendix B describes two functions setjmp and longjmp for something called non-local jumps. Apart from the basic understanding that setjmp saves the state information and longjmp restores the state, I haven't been able to understand the exact flow and use cases for this feature.

So, what exactly does this feature accomplish and where is it useful?

Jens
  • 69,818
  • 15
  • 125
  • 179
Tapan Nallan
  • 1,762
  • 3
  • 17
  • 37
  • 1
    I implemented user mode thread library using setjmp and long jump. No assembly whatsoever the context switchis aachieved by lngjmp – stdcall May 19 '13 at 15:42

1 Answers1

6

As for the control flow: setjmp returns twice, and longjmp never returns. When you call setjmp for the first time, to store the environment, it returns zero, and the when you call longjmp, the control flow passes to return from setjmp with the value provided in the argument.

(Note that setjmp needn't actually be functions; it may well be a macro. longjmp is a function, though.)

Use cases are generally cited as "error handling", and "don't use these functions".

Here's a little control flow example:

jmp_buf env;

void foo()
{
    longjmp(&env, 10);                      +---->----+
}                                           |         |
                                            |         |
int main()              (entry)---+         ^         V
{                                 |         |         |
    if(setjmp(&env) == 0)         | (= 0)   |         | (= 10)
    {                             |         ^         |
        foo();                    +---->----+         |
    }                                                 +---->----+
    else                                                        |
    {                                                           |
        return 0;                                               +--- (end)
    }
}

Notes:

  • You cannot pass 0 to longjmp. If you do, 1 is returned by setjmp.

  • You must not return from the function that called setjmp before the corresponding longjmp. In other words, longjmp must only be called above setjmp in the call stack.

  • (Thanks to @wildplasser:) You cannot actually store the result of setjmp. If you want to return in several different ways, you can use a switch, though:

    switch (setjmp(&env))
    {
    case 0:   // first call
    case 2:   // returned from longjmp(&env, 2)
    case 5:   // returned from longjmp(&env, 5)
    // etc.
    }
    
Hasturkun
  • 35,395
  • 6
  • 71
  • 104
Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • 1
    Wrong. You **should not assign** the "return value" from setjmp(). You may only *evaluate* it. – wildplasser May 19 '13 at 15:34
  • @wildplasser: Interesting, do you have a reference for that? – Kerrek SB May 19 '13 at 15:35
  • Googling it ... I came up in c.l.c a few years ago. BRB – wildplasser May 19 '13 at 15:38
  • @wildplasser: You're right, it might be forbidden by 7.13.1.1/4 in C11. – Kerrek SB May 19 '13 at 15:44
  • Here is one: https://www.securecoding.cert.org/confluence/display/seccode/MSC22-C.+Use+the+setjmp%28%29,+longjmp%28%29+facility+securely . Here is a usenet mirror: http://coding.derkeiler.com/Archive/C_CPP/comp.lang.c/2009-07/msg01601.html – wildplasser May 19 '13 at 15:44
  • 1
    C99 `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 integer 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; the entire expression of an expression statement (possibly cast to void).` – milleniumbug May 19 '13 at 15:46
  • Thanks for the detailed answer. I really appreciate the effort. But how is this better than a simple function call + return seeing that setjmp has the restriction of not being able to assign the return value? – Tapan Nallan May 19 '13 at 16:04
  • @rusticbit: I don't think it's "better"... it's just another tool, and you can use it non-locally, i.e. you can return a long way. It's a little bit like a poor man's C++ exception. (And as the documentation says, you're encouraged *not* to use it.) – Kerrek SB May 19 '13 at 16:10
  • I presume you meant `if( !setjmp(&env)) ... ` ? – wildplasser May 19 '13 at 16:13