setjmp

来自cppreference.com
< c‎ | program
定义于头文件 <setjmp.h>
#define setjmp(env) /* implementation-defined */

将当前执行环境保存到 jmp_buf 类型对象 env 。此对象可在之后被 longjmp 函数用来恢复当前执行环境。即当调用 longjmp 函数时,执行将从传递给 longjmpjmp_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

参阅

跳转到指定位置
(函数)