std::longjmp
| Definiert in Header <csetjmp> |
||
| void longjmp( std::jmp_buf env, int status ); |
(bis C++17) | |
| [[noreturn]] void longjmp( std::jmp_buf env, int status ); |
(seit C++17) | |
Lädt den Ausführungskontext env, der durch einen früheren Aufruf von setjmp gespeichert wurde. Diese Funktion kehrt nicht zurück. Die Kontrolle wird an die Aufrufstelle des Makros setjmp übertragen, das env eingerichtet hat. Dieses setjmp gibt dann den als status übergebenen Wert zurück.
Wenn die Funktion, die setjmp aufgerufen hat, beendet wurde, ist das Verhalten undefiniert (mit anderen Worten, nur Sprünge nach oben im Aufrufstapel sind erlaubt).
Inhalt |
[bearbeiten] Zusätzliche Einschränkungen in C++
Über das C-longjmp hinaus hat C++ std::longjmp ein eingeschränkteres Verhalten.
Wenn das Ersetzen von std::longjmp durch throw und setjmp durch catch einen nicht-trivialen Destruktor für ein automatisches Objekt aufrufen würde, ist das Verhalten eines solchen std::longjmp undefiniert.
|
Das Verhalten ist undefiniert, wenn |
(seit C++20) |
[bearbeiten] Parameter
| env | - | Variable, die den von setjmp gespeicherten Zustand des Programmablaufs bezeichnet |
| status | - | der Wert, der von setjmp zurückgegeben werden soll. Wenn er gleich 0 ist, wird stattdessen 1 verwendet. |
[bearbeiten] Rückgabewert
(keine)
[bearbeiten] Hinweise
std::longjmp ist der Mechanismus, der in C zur Behandlung unerwarteter Fehlerbedingungen verwendet wird, bei denen die Funktion nicht sinnvoll zurückkehren kann. C++ verwendet im Allgemeinen die Exception-Behandlung für diesen Zweck.
[bearbeiten] 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); // Go to error handler 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)) { // Error handler for solver std::cout << "No real solution\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
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 real solution
[bearbeiten] Defect reports
Die folgenden Verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
| DR | angewendet auf | Verhalten wie veröffentlicht | Korrigiertes Verhalten |
|---|---|---|---|
| LWG 619 | C++98 | die Formulierung der zusätzlichen Einschränkungen in C++ war vage | verbesserte die Formulierung |
| LWG 894 | C++98 | das Verhalten war undefiniert, wennstd::longjmp durch throw und setjmp durchcatch ersetzt würde, um irgendein automatisches Objekt zu zerstören |
das Verhalten ist nur undefiniert wenn ein nicht-trivialer Destruktor für ein beliebiges automatisches Objekt aufgerufen wird |
[bearbeiten] Siehe auch
| speichert den Kontext (Funktionsmakro) | |
| C-Dokumentation für longjmp
| |