setjmp

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

保存当前执行环境到 std::jmp_buf 类型变量 envstd::longjmp 函数稍后可用此变量恢复当前执行环境。即在调用 std::longjmp 函数时,执行在构造了传递给 std::longjmpstd::jmp_buf 特定调用点继续。该情况下 setjmp 返回传递给 std::longjmp 的值。

setjmp 的调用必须只出现在下列语境之一:

switch(setjmp(env)) { ..
  • 比较或等于运算符的运算数之一,而另一运算数是整数常量表达式,产生的表达式是 ifswitchwhiledo-whilefor 语句的整个控制表达式。
if(setjmp(env) > 0) { ...
  • 一元 ! 运算符的运算数,产生的表达式是 ifswitchwhiledo-whilefor 语句的整个控制表达式。
while(!setjmp(env)) { ...
setjmp(env);

setjmp 出现于任何其他语境,则行为未定义。

一旦返回到 setjmp 的作用域,所有可访问对象、浮点状态标志及其他抽象机组件拥有与在执行 std::longjmp 时相同的值,除了 setjmp 的作用域中的非 volatile 局部对象,若它们在 setjmp 调用后被更改,则其值是不确定的。

参数

env - 保存程序执行状态的变量。

返回值

若宏被原始代码调用且执行环境存储于 env 则返回 0

若刚进行了非局部跳转则返回非零值。返回值同传递给 std::longjmp 的值。

示例

#include <iostream>
#include <csetjmp>
 
std::jmp_buf jump_buffer;
 
[[noreturn]] void a(int count) 
{
    std::cout << "a(" << count << ") called\n";
    std::longjmp(jump_buffer, count+1);  // setjump() 将返回 count+1
}
 
int main()
{
    volatile int count = 0; // 在 setjmp 作用域中被修改的局部变量必须是 volatile
    if (setjmp(jump_buffer) != 9) { // 在一个 if 内不等于常量表达式
        a(++count);  // 这会导致 setjmp() 退出
    }
}

输出:

a(1) called
a(2) called
a(3) called
a(4) called
a(5) called
a(6) called
a(7) called
a(8) called

参阅

跳转到指定位置
(函数)