setjmp
From cppreference.com
| ヘッダ <csetjmp> で定義 |
||
| #define setjmp(env) /* 実装定義 */ |
||
現在の実行コンテキストを、型 std::jmp_buf の変数 env に保存します。この変数は、後で std::longjmp 関数によって現在の実行コンテキストを復元するために使用できます。つまり、std::longjmp 関数の呼び出しが行われると、実行は、std::longjmp に渡された std::jmp_buf 変数を構築した特定の呼び出しサイトから再開されます。その場合、setjmp は std::longjmp に渡された値を返します。
setjmp の呼び出しは、次のいずれかのコンテキストにのみ出現する必要があります。
- if、switch、while、do-while、for の完全な制御式。
switch (setjmp(env)) { // ...
- 関係演算子または等価演算子のオペランドの1つで、もう一方のオペランドが整数定数式であり、結果の式が if、switch、while、do-while、for の完全な制御式となる場合。
if (setjmp(env) > 0) { // ...
- 単項 ! 演算子のオペランドで、結果の式が if、switch、while、do-while、for の完全な制御式となる場合。
while (!setjmp(env)) { // ...
- 式文の完全な式(void にキャストされる場合がある)。
setjmp(env);
setjmp が上記以外のコンテキストで出現する場合、動作は未定義です。
|
さらに、 |
(C++20以降) |
setjmp のスコープに戻ったとき
- アクセス可能なすべてのオブジェクト、浮動小数点ステータスフラグ、および抽象マシンのその他のコンポーネントは、std::longjmp が実行されたときの値と同じ値になります。
- ただし、volatile でない、
setjmpの呼び出しを含む関数内のローカル変数は、setjmpの呼び出し以降に変更されている場合、その値は不定です。
目次 |
[編集] パラメータ
| env | - | プログラムの実行状態を保存する変数 |
[編集] 戻り値
0 マクロが元のコードによって呼び出され、実行コンテキストが env に保存された場合。
非ローカルジャンプが実行された直後の場合、ゼロ以外の値。戻り値は std::longjmp に渡された値と同じです。
[編集] 注意
上記の要件により、setjmp の戻り値をデータフロー(例:オブジェクトの初期化または代入)で使用することは禁止されています。戻り値は、制御フローでのみ使用するか、破棄することができます。
[編集] 例
このコードを実行
#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; }
出力
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
[編集] 関連項目
| 指定された場所にジャンプする (関数) | |
| C のドキュメント for setjmp
| |