#C 语言标准库函数 setjmp
#define setjmp(env) /* 由具体实现定义 */
说明
将当前执行上下文保存到 jmp_buf
类型的变量 env
中,这个变量可在之后用于 longjmp 函数恢复当前执行上下文。
可以在以下位置调用 setjmp
保存执行上下:
-
整个表达式语句
setjmp(env);
-
if
,switch
,while
,do-while
,for
的整个控制表达式switch (setjmp(env)) { /* ... */ }
-
一元运算符
!
的操作数,运算结果为if
,switch
,while
,do-while
,for
的整个控制表达式while (!setjmp(env)) { /* ... */ }
-
关系运算符的第一个操作数,并且另一个操作数是常量表达式,关系运算的结果为
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
。
参数
env
- 用于保存当前执行上下文
返回值
#示例
#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