std::longjmp
| Definido en el encabezado <csetjmp>
|
||
void longjmp( std::jmp_buf env, int status );
|
(hasta C++17) | |
[[noreturn]] void longjmp( std::jmp_buf env, int status );
|
(desde C++17) | |
Carga el contexto de ejecución env guardado por una llamada anterior a setjmp. Esta función no retorna. El control se transfiere al lugar de la llamada de la macro setjmp que estableció env. Esa setjmp entonces retorna el valor, pasado como el status.
Si la función que llamó a setjmp ha finalizado, el comportamiento no está definido (en otras palabras, solo se permiten saltos largos hacia arriba en la pila de llamadas).
Restricciones adicionales en C++
Además de C
longjmp
, C++
std::longjmp
tiene un comportamiento más restringido.
Si reemplazar
std::longjmp
con
throw
y
setjmp
con
catch
invocaría un
destructor no trivial
para cualquier objeto automático, el comportamiento de dicho
std::longjmp
es indefinido.
|
El comportamiento es indefinido si
|
(since C++20) |
Parámetros
| env | - | variable que hace referencia al estado de ejecución del programa guardado por setjmp |
| status | - | el valor a retornar desde setjmp . Si es igual a 0 , 1 se utiliza en su lugar |
Notas
std::longjmp
es el mecanismo utilizado en C para manejar condiciones de error inesperadas donde la función no puede retornar de manera significativa. C++ generalmente utiliza
manejo de excepciones
para este propósito.
Ejemplo
#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); // Ir al manejador de errores 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)) { // Manejador de errores para el solver std::cout << "No hay solución real\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; }
Salida:
Solving 1x² + -3x + 2 = 0... x₁ = 1, x₂ = 2 Solving 2x² + -3x + -2 = 0... x₁ = -0.5, x₂ = 2 Solving 1x² + 2x + 3 = 0... No hay solución real
Informes de defectos
Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares de C++ publicados anteriormente.
| DR | Aplicado a | Comportamiento publicado | Comportamiento correcto |
|---|---|---|---|
| LWG 619 | C++98 | la redacción de las restricciones adicionales en C++ era vaga | se mejoró la redacción |
| LWG 894 | C++98 |
el comportamiento era indefinido si reemplazar
std::longjmp
con
throw
y
setjmp
con
catch destruiría cualquier objeto automático |
el comportamiento solo es indefinido
si se invoca un destructor no trivial para cualquier objeto automático |
Véase también
|
guarda el contexto
(macro de función) |
|
|
Documentación de C
para
longjmp
|
|