c / expert
Snippet
Non-Local Execution Control Flow and Exception Emulation via setjmp and longjmp
The standard C header <setjmp.h> provides low-level non-local jumps bypassing standard call stack unwind mechanisms. Calling setjmp stores CPU register states in a jmp_buf environment, returning 0 on setup and non-zero when jump destination is triggered by longjmp. Local variables modified between setjmp and longjmp must be declared volatile to prevent compiler optimizations from clobbering them when registers are restored.
snippet.c
c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <stdio.h>#include <setjmp.h>static jmp_buf execution_context;void deep_calculation(volatile int *status_code) {if (*status_code < 0) {/* Perform non-local goto restoring stack context saved by setjmp */longjmp(execution_context, 404);}}int main(void) {/* Variables modified between setjmp and longjmp must be volatile to prevent clobbering */volatile int state = -1;int result = setjmp(execution_context);if (result == 0) {printf("Context saved. Executing operation...\n");deep_calculation(&state);} else {printf("Caught exception with code: %d\n", result);}return 0;}
Breakdown
1
volatile int state = -1;
Marks the variable volatile so its value survives register restoration during longjmp stack unwinding.
2
int result = setjmp(execution_context);
Saves calling environment register state, returning 0 directly or non-zero when restored via longjmp.