#includejmp_buf env; // 保存 CPU 狀態(PC, SP, 通用暫存器等) int setjmp(jmp_buf env); // 首次調用返回 0,長跳轉返回非 0 void longjmp(jmp_buf env, int val); // 恢復 env 狀態,setjmp 返回 val
setjmp,再呼叫 longjmp。longjmp 必須在 setjmp 所在函數尚未返回時調用(棟樑仍有效)。setjmp 封裝在輔助函數中(輔助函數返回後棟樑失效)。#include#include jmp_buf buf; void second(void) { puts("second"); longjmp(buf, 1); // 跳回 main 的 setjmp } void first(void) { second(); puts("first"); // 不會執行 } int main(void) { if (setjmp(buf) == 0) first(); else puts("main"); // longjmp 後執行這裡 return 0; }
輸出:second\nmain
int try(jmp_buf *b) { return setjmp(*b); } // 錯誤!setjmp 在 try 棟樑
void throw(jmp_buf *b) { longjmp(*b, 1); } // 呼叫時 try 已返回,棟樑無效
| 特性 | setjmp/longjmp | ucontext (POSIX) |
|---|---|---|
| 標準 | C89/C99 | POSIX.1-2001 (已移除 POSIX.1-2008) |
| 功能 | 非局部跳轉 | 完整上下文切換(含信號遮罩) |
| 協程庫基礎 | 早期 libtask, protothreads | libco, libucontext, boost.coroutine |
| 可移植性 | 極高 | Unix-like,Windows 需模擬 |