Namespaces
Variants

setjmp

From cppreference.net
Utilities library
Definiert im Header <csetjmp>
#define setjmp(env) /* implementation-defined */

Speichert den aktuellen Ausführungskontext in einer Variable env vom Typ std::jmp_buf . Diese Variable kann später verwendet werden, um den aktuellen Ausführungskontext durch die std::longjmp -Funktion wiederherzustellen. Das bedeutet, wenn ein Aufruf der std::longjmp -Funktion erfolgt, setzt die Ausführung an der bestimmten Aufrufstelle fort, die die std::jmp_buf -Variable erstellt hat, die an std::longjmp übergeben wurde. In diesem Fall gibt setjmp den Wert zurück, der an std::longjmp übergeben wurde.

Der Aufruf von setjmp darf nur in einem der folgenden Kontexte erscheinen:

  1. der gesamte steuernde Ausdruck von if , switch , while , do-while , for .
    switch (setjmp(env)) { // ...
  2. ein Operand eines relationalen oder Gleichheitsoperators, wobei der andere Operand ein ganzzahliger konstanter Ausdruck ist und der resultierende Ausdruck der gesamte steuernde Ausdruck von if , switch , while , do-while , for ist.
    if (setjmp(env) > 0) { // ...
  3. der Operand eines unären !-Operators, wobei der resultierende Ausdruck der gesamte steuernde Ausdruck von if , switch , while , do-while , for ist.
    while (!setjmp(env)) { // ...
  4. der gesamte Ausdruck eines Ausdrucksstatements (möglicherweise gecastet zu void ).
    setjmp(env);

Wenn setjmp in einem anderen Kontext erscheint, ist das Verhalten undefiniert.

Zusätzlich ist das Verhalten undefiniert, wenn setjmp in einer Coroutine an einer Stelle aufgerufen wird, an der der co_await Operator verwendet werden kann.

(seit C++20)

Bei Rückkehr in den Gültigkeitsbereich von setjmp :

  • alle zugänglichen Objekte, Gleitkomma-Statusflags und andere Komponenten der abstrakten Maschine haben dieselben Werte wie zu dem Zeitpunkt, als std::longjmp ausgeführt wurde,
  • mit Ausnahme der nicht- volatile lokalen Variablen in der Funktion, die den Aufruf von setjmp enthält, deren Werte undefiniert sind, falls sie seit dem setjmp -Aufruf verändert wurden.

Inhaltsverzeichnis

Parameter

env - Variable zum Speichern des Ausführungszustands des Programms

Rückgabewert

0 wenn das Makro vom ursprünglichen Code aufgerufen wurde und der Ausführungskontext in env gespeichert wurde.

Nicht-Null-Wert, falls soeben ein nicht-lokaler Sprung ausgeführt wurde. Der Rückgabewert entspricht dem an std::longjmp übergebenen Wert.

Hinweise

Die oben genannten Anforderungen verbieten die Verwendung des Rückgabewerts von setjmp im Datenfluss (z.B. um ein Objekt damit zu initialisieren oder zuzuweisen). Der Rückgabewert darf nur entweder in der Kontrollflusssteuerung verwendet oder verworfen werden.

Beispiel

#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); // Zum Fehlerbehandler springen
    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("Löse {}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))
    {
        // Fehlerbehandler für den Löser
        std::cout << "Keine reelle Lösung\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;
}

Ausgabe:

Löse 1x² + -3x + 2 = 0...
x₁ = 1, x₂ = 2
Löse 2x² + -3x + -2 = 0...
x₁ = -0.5, x₂ = 2
Löse 1x² + 2x + 3 = 0...
Keine reelle Lösung

Siehe auch

springt zu angegebenem Ort
(Funktion)
C-Dokumentation für setjmp