Namespaces
Variants

std:: longjmp

From cppreference.net
Utilities library
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 previa a setjmp . Esta función no retorna. El control se transfiere al sitio de llamada de la macro setjmp que configuró env . Ese setjmp luego retorna el valor, pasado como el status .

Si la función que llamó a setjmp ha finalizado, el comportamiento es indefinido (en otras palabras, solo se permiten saltos largos hacia arriba en la pila de llamadas).

Contenidos

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 std::longjmp es llamado en una coroutine en un lugar donde el operador co_await puede ser utilizado.

(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

Valor de retorno

(ninguno)

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)