std:: longjmp
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Program termination | |||||||||||||||||||||
|
|||||||||||||||||||||
| Unreachable control flow | |||||||||||||||||||||
|
(C++23)
|
|||||||||||||||||||||
| Communicating with the environment | |||||||||||||||||||||
| Signals | |||||||||||||||||||||
| Signal types | |||||||||||||||||||||
| Non-local jumps | |||||||||||||||||||||
|
|||||||||||||||||||||
| Types | |||||||||||||||||||||
|
定义于头文件
<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
替换
std::longjmp
并使用
catch
替换
setjmp
会调用任何自动对象的
非平凡析构函数
,则此类
std::longjmp
的行为是未定义的。
|
如果在
协程
中可能使用
co_await
运算符的位置调用
|
(since C++20) |
参数
| env | - | 指向由 setjmp 保存的程序执行状态的变量 |
| status | - | 从 setjmp 返回的值。若等于 0 ,则改用 1 |
返回值
(无)
注释
std::longjmp
是 C 语言中用于处理函数无法正常返回的意外错误情况的机制。C++ 通常使用
异常处理
来实现这一目的。
示例
#include <array> #include <cmath> #include <csetjmp> #include <cstdlib> #include <format> #include <iostream> std::jmp_buf solver_error_handler; std::array<double, 2> solve_quadratic_equation(double a, double b, double c) { const double discriminant = b * b - 4.0 * a * c; if (discriminant < 0) std::longjmp(solver_error_handler, true); // 跳转至错误处理程序 const double delta = std::sqrt(discriminant) / (2.0 * a); const double argmin = -b / (2.0 * a); return {argmin - delta, argmin + delta}; } void show_quadratic_equation_solution(double a, double b, double c) { std::cout << std::format("求解 {}x² + {}x + {} = 0...\n", a, b, c); auto [x_0, x_1] = solve_quadratic_equation(a, b, c); std::cout << std::format("x₁ = {}, x₂ = {}\n\n", x_0, x_1); } int main() { if (setjmp(solver_error_handler)) { // 求解器的错误处理程序 std::cout << "无实数解\n"; return EXIT_FAILURE; } for (auto [a, b, c] : {std::array{1, -3, 2}, {2, -3, -2}, {1, 2, 3}}) show_quadratic_equation_solution(a, b, c); return EXIT_SUCCESS; }
输出:
求解 1x² + -3x + 2 = 0... x₁ = 1, x₂ = 2 求解 2x² + -3x + -2 = 0... x₁ = -0.5, x₂ = 2 求解 1x² + 2x + 3 = 0... 无实数解
缺陷报告
下列行为变更缺陷报告被追溯应用于先前发布的 C++ 标准。
| 缺陷报告 | 适用标准 | 发布时行为 | 正确行为 |
|---|---|---|---|
| LWG 619 | C++98 | C++中额外限制的措辞表述模糊 | 改进了措辞表述 |
| LWG 894 | C++98 |
若将
std::longjmp
替换为
throw
并将
setjmp
替换为 catch 会销毁任何自动对象,则行为未定义 |
仅当调用任何自动对象的
非平凡析构函数时行为未定义 |
参见
|
保存执行上下文
(函数宏) |
|
|
C 文档
关于
longjmp
|
|