std::longjmp
来自cppreference.com
在标头 <csetjmp> 定义
|
||
void longjmp( std::jmp_buf env, int status ); |
(C++17 前) | |
[[noreturn]] void longjmp( std::jmp_buf env, int status ); |
(C++17 起) | |
加载先前的 setjmp 调用所保存的执行环境 env。此函数不会返回。控制被转移到设置了 env 的宏 setjmp 的调用点。该 setjmp 随后返回作为 status 传递的值。
如果调用了 setjmp 的函数已退出,那么行为未定义(也就是说只允许在调用栈向上长跳)
C++ 的额外限制
在 C 的 longjmp 基础上,C++ 的 std::longjmp
的行为受到更多限制。
如果分别以 throw 和 catch 替换 std::longjmp
和 setjmp 会执行任何自动对象的非平凡析构函数,那么这种 std::longjmp
的行为未定义。
在协程中可以使用 co_await 运算符的地方调用 |
(C++20 起) |
参数
env | - | 指代 setjmp 所保存的函数执行状态的变量 |
status | - | 从 setjmp 返回的值。如果它等于 0,那么用 1 代替 |
返回值
(无)
注意
longjmp
是 C 中处理函数无法有意义返回处的错误条件的机制。C++ 通常为此目的使用异常处理。
示例
运行此代码
#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)
缺陷报告
下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。
缺陷报告 | 应用于 | 出版时的行为 | 正确行为 |
---|---|---|---|
LWG 619 | C++98 | C++ 额外限制的描述用词比较模糊 | 改进用词 |
LWG 894 | C++98 | 分别以 throw 和 catch 替换 std::longjmp 和 setjmp 会销毁任何自动对象时的行为未定义 |
只有在这种情况下会执行任何自动对象 的非平凡析构函数时行为才会未定义 |
参阅
保存语境 (宏函数) |