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的相同。

[编辑] 示例

#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 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

[编辑] 参阅

跳转到指定位置
(函数) [edit]
setjmpC++文档