std::longjmp
| Определён в заголовке <csetjmp>
|
||
void longjmp( std::jmp_buf env, int status );
|
(до C++17) | |
[[noreturn]] void longjmp( std::jmp_buf env, int status );
|
(начиная с C++17) | |
Загружает контекст исполнения env, сохранённый предыдущим вызовом setjmp. Эта функция не возвращается. Управление передаётся в точку вызова макроса setjmp, который настроил env. Этот setjmp затем возвращает значение, переданное как status.
Если функция, вызвавшая setjmp, уже завершилась, поведение не определено (другими словами, разрешены только длинные прыжки вверх по стеку вызовов).
Дополнительные ограничения в C++
В дополнение к C
longjmp
, C++
std::longjmp
имеет более ограниченное поведение.
Если замена
std::longjmp
на
throw
и
setjmp
на
catch
привела бы к вызову
нетривиального деструктора
для любого автоматического объекта, поведение такого
std::longjmp
является неопределённым.
|
Поведение не определено, если
|
(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("Solving {}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; }
Вывод:
Solving 1x² + -3x + 2 = 0... x₁ = 1, x₂ = 2 Solving 2x² + -3x + -2 = 0... x₁ = -0.5, x₂ = 2 Solving 1x² + 2x + 3 = 0... Нет действительных решений
Отчеты о дефектах
Следующие отчеты об изменениях поведения, влияющие на дефекты, были применены ретроактивно к ранее опубликованным стандартам C++.
| DR | Применяется к | Поведение в опубликованной версии | Корректное поведение |
|---|---|---|---|
| LWG 619 | C++98 | формулировка дополнительных ограничений в C++ была нечеткой | улучшена формулировка |
| LWG 894 | C++98 |
поведение было неопределенным, если замена
std::longjmp
на
throw
и
setjmp
на
catch приводила бы к уничтожению любого автоматического объекта |
поведение неопределено только
если вызывается нетривиальный деструктор для любого автоматического объекта |
Смотрите также
|
сохраняет контекст
(макрос функции) |
|
|
C documentation
для
longjmp
|
|