Namespaces
Variants

setjmp

From cppreference.net
定义于头文件 <setjmp.h>
#define setjmp(env) /* 由实现定义 */

将当前执行上下文保存到类型为 jmp_buf 的变量 env 中。该变量后续可通过 longjmp 函数用于恢复当前执行上下文。即当调用 longjmp 函数时,执行将在构造传递给 longjmp jmp_buf 变量的特定调用点继续。此时 setjmp 将返回传递给 longjmp 的值。

setjmp 的调用只能出现在以下任一语境中:

  1. if switch while do-while for 语句的完整控制表达式。
    switch(setjmp(env)) { // ...
  2. 关系或相等运算符的一个操作数(另一个操作数为整型常量表达式),且该表达式为 if switch while do-while for 语句的完整控制表达式。
    if(setjmp(env) > 10) { // ...
  3. 一元 ! 运算符的操作数,且该表达式为 if switch while do-while for 语句的完整控制表达式。
    while(!setjmp(env)) { // ...
  4. 表达式语句 的完整表达式(可强制转换为 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 my_jump_buffer;
noreturn void foo(int status) 
{
    printf("foo(%d) called\n", status);
    longjmp(my_jump_buffer, status + 1); // 将从setjmp返回status+1
}
int main(void)
{
    volatile int count = 0; // 在setjmp作用域内修改的局部变量必须为volatile
    if (setjmp(my_jump_buffer) != 5) // 在if语句中与常量比较
        foo(++count);
}

输出:

foo(1) called
foo(2) called
foo(3) called
foo(4) called

参考文献

  • C17 标准 (ISO/IEC 9899:2018):
  • 7.13.1.1 setjmp 宏 (p: 191)
  • C11 标准 (ISO/IEC 9899:2011):
  • 7.13.1.1 setjmp 宏 (p: 262-263)
  • C99标准(ISO/IEC 9899:1999):
  • 7.13.1.1 setjmp宏(页码:243-244)
  • C89/C90 标准 (ISO/IEC 9899:1990):
  • 4.6.1 setjmp 宏

参见

跳转至指定位置
(函数)
C++ 文档 关于 setjmp