setjmp
来自cppreference.com
定义于头文件 <setjmp.h>
|
||
#define setjmp(env) /* implementation-defined */ |
||
将当前执行环境保存到 jmp_buf 类型对象 env
。此对象可在之后被 longjmp 函数用来恢复当前执行环境。即当调用 longjmp 函数时,执行将从传递给 longjmp 的 jmp_buf 对象所构建的特定调用点继续。该情况下 setjmp 返回传递给 longjmp 的值。
setjmp
的调用必须只出现在下列语境之一中:
- 选择或迭代语句( if 、 switch 、 for 、 while 、 do-while )的完整控制表达式
switch(setjmp(env)) { ..
- 比较或相等运算符的一个运算数,另一运算数为整数常量表达式,产生的表达式为选择或迭代语句的完整控制表达式
if(setjmp(env) > 10) { ...
- 一元 ! 运算符的运算数,其结果为选择或迭代语句的完整控制表达式
while(!setjmp(env)) { ...
- 表达式语句的完整表达式(可以将其转型到
void
)。
setjmp(env);
若 setjmp
出现于其他语境中,则行为未定义。
一旦返回到 setjmp
的作用域,所有可访问对象、浮点状态标志及其他抽象机组件拥有与在执行 longjmp 时相同的值,除了含有 setjmp
调用的函数中的非 volatile 局部对象,在 setjmp
调用后更改它们,则其值不确定。
参数
env | - | 要保存程序执行状态的对象。 |
返回值
若原初代码调用该宏,则返回 0 ,并保存执行环境到 env
。
若进行了非局部跳转则可返回非零值。返回值与传递给 longjmp 者相同。
注解
上述要求禁止在数据流中使用 setjmp
的返回值(例如以之初始化或赋值对象)。只能将返回值用于控制流或舍弃。
示例
运行此代码
#include <stdio.h> #include <setjmp.h> #include <stdnoreturn.h> jmp_buf jump_buffer; noreturn void a(int count) { printf("a(%d) called\n", count); longjmp(jump_buffer, count+1); // 将从 setjmp 外 count+1 } int main(void) { volatile int count = 0; // setjmp 作用域内要修改的局部变量必须为 volatile if (setjmp(jump_buffer) != 9) // 在一个 if 内与常数比较 a(count++); }
输出:
a(0) called a(1) called a(2) called a(3) called a(4) called a(5) called a(6) called a(7) called a(8) called
引用
- C11 标准(ISO/IEC 9899:2011):
- 7.13.1.1 The setjmp macro (p: 262-263)
- C99 标准(ISO/IEC 9899:1999):
- 7.13.1.1 The setjmp macro (p: 243-244)
- C89/C90 标准(ISO/IEC 9899:1990):
- 4.6.1 The setjmp macro
参阅
跳转到指定位置 (函数) |