setjmp
来自cppreference.com
在标头 <csetjmp> 定义
|
||
#define setjmp(env) /* 由实现定义 */ |
||
保存当前执行环境到 std::jmp_buf 类型变量 env。std::longjmp 函数稍后可用此变量恢复当前执行环境。即在调用 std::longjmp 函数时,执行在构造了传递给 std::longjmp 的 std::jmp_buf 特定调用点继续。此时 setjmp
返回传递给 std::longjmp 的值。
setjmp
的调用必须只能在下列语境出现:
switch(setjmp(env)) { ..
if(setjmp(env) > 0) { ...
while(!setjmp(env)) { ...
- 表达式语句(可以转型到 void)的整个表达式。
setjmp(env);
如果 setjmp
在其他语境出现,那么行为未定义。
在协程中可以使用 co_await 运算符的地方调用 |
(C++20 起) |
一旦返回到 setjmp
的作用域:
- 所有可访问对象、浮点状态标志及其他抽象机组件拥有与在执行 std::longjmp 时相同的值
- 除了含有
setjmp
调用的函数中的非 volatile 局部对象,如果在setjmp
调用后更改它们,那么它们的值不确定。
参数
env | - | 保存程序执行状态的变量 |
返回值
如果宏被原始代码调用且执行环境在 env 存储,那么返回 0。
如果刚才进行了非局部跳转,那么返回非零值。返回值与传递给 std::longjmp 的值相同。
注解
上述要求禁止在数据流中使用 setjmp
的返回值(例如用它初始化或赋值对象)。只能将返回值用于控制流或舍弃。
示例
运行此代码
#include <csetjmp> #include <iostream> std::jmp_buf my_jump_buffer; [[noreturn]] void foo(int status) { std::cout << "调用 foo(" << status << ")\n"; std::longjmp(my_jump_buffer, status + 1); // setjmp() 会返回 status + 1 } int main() { volatile int count = 0; // setjmp 修改的局部变量必须是 volatile 的 if (setjmp(my_jump_buffer) != 5) // 在 if 内与常量表达式比较相等 { count = count + 1; // ++count 和 count += 1 等在 volatile 左操作数 // 上的操作从 C++20(P1152)起被弃用, // 但从 C++23(P2327)起解除弃用。 foo(count); // 这会导致 setjmp() 退出 } }
输出:
调用 foo(1) 调用 foo(2) 调用 foo(3) 调用 foo(4)
参阅
跳转到指定位置 (函数) |