国际访客建议访问 Primers 编程伙伴 国际版站点 > C 教程 > setjmp 以获得更好的体验。

# C 语言标准库函数 setjmp

在头文件 setjmp.h 中定义。
#define setjmp(env) /* 由具体实现定义 */

!subtitle:说明

将当前执行上下文保存到 jmp_buf 类型的变量 env 中,这个变量可在之后用于 longjmp 函数恢复当前执行上下文。

可以在以下位置调用 setjmp 保存执行上下:

  1. 整个表达式语句

    setjmp(env);
    

  2. if, switch, while, do-while, for 的整个控制表达式

    switch (setjmp(env)) { /* ... */ }
    

  3. 一元运算符 ! 的操作数,运算结果为 if, switch, while, do-while, for 的整个控制表达式

    while (!setjmp(env))  { /* ... */ }
    

  4. 关系运算符的第一个操作数,并且另一个操作数是常量表达式,关系运算的结果为 if, switch, while, do-while, for 的整个控制表达式

    if (setjmp(env) > 10)  { /* ... */ }
    

在其它上下文中调用 setjmp 是未定义行为。

调用 longjmp 函数时,程序会回到 setjmp 保存上下文的位置继续进行,setjmp 会返回 longjmp 的第二个参数。

  • 除了 setjmp 所在函数的非 volatile 局部变量以外,所有可访问的对象、浮点状态标志以及所有其它组件的值都是调用 longjmp 函数时的值,而不是 setjmp 保存上下文时的值。

  • setjmp 所在函数的非 volatile 局部变量的值为 setjmp 保存上下文时的值,且调用 setjmp 后不可进行修改,否则该变量的值在调用 longjmp 函数返回后是不确定的。

  • 如果需要在调用 setjmp 后修改所在函数的局部变量,则该局部变量应当声明为 volatile

!subtitle:参数

  • env - 用于保存当前执行上下文

!subtitle:返回值

  • 调用时,保存当前执行上下文,返回 0

  • 通过 longjmp 函数恢复上下文时,返回 longjmp 函数的第二个参数

# 示例

#include <stdio.h>
#include <setjmp.h>
#include <stdnoreturn.h>
 
// 保存上下文的变量
jmp_buf env;
 
void func(int status) 
{
    printf("调用 func(%d)\n", status);
    longjmp(env, status); // 跳转,setjmp 返回 status
}
 
int main(void)
{
    volatile int count = 0; // 这个变量在 setjmp 之后会被修改,因此声明为 volatile

    if (setjmp(env) < 5)    // 保存上下文,检查返回值
        func(count++);      // 修改了 count 的值

    return 0;
}

运行结果:

调用 func(0)
调用 func(1)
调用 func(2)
调用 func(3)
调用 func(4)
调用 func(5)

# 推荐阅读

# 外部参考

# 参考标准

  • C17 standard (ISO/IEC 9899:2018):

    • 7.13.1.1 The setjmp macro (p: 191)

  • C11 standard (ISO/IEC 9899:2011):

    • 7.13.1.1 The setjmp macro (p: 262-263)

  • C99 standard (ISO/IEC 9899:1999):

    • 7.13.1.1 The setjmp macro (p: 243-244)

  • C89/C90 standard (ISO/IEC 9899:1990):

    • 4.6.1 The setjmp macro

本文 更新于: 2025-11-27 09:38:10 创建于: 2025-11-27 09:38:10