名前空間
変種
操作

setjmp

From cppreference.com
 
 
ユーティリティライブラリ
言語サポート
型のサポート (基本型、RTTI)
ライブラリ機能検査マクロ (C++20)
プログラムユーティリティ
可変引数関数
コルーチンサポート (C++20)
契約サポート (C++26)
三方比較
(C++20)
(C++20)(C++20)(C++20)  
(C++20)(C++20)(C++20)

汎用ユーティリティ
関係演算子 (C++20で非推奨)
 
 
ヘッダ <csetjmp> で定義
#define setjmp(env) /* 実装定義 */

現在の実行コンテキストを、型 std::jmp_buf の変数 env に保存します。この変数は、後で std::longjmp 関数によって現在の実行コンテキストを復元するために使用できます。つまり、std::longjmp 関数の呼び出しが行われると、実行は、std::longjmp に渡された std::jmp_buf 変数を構築した特定の呼び出しサイトから再開されます。その場合、setjmpstd::longjmp に渡された値を返します。

setjmp の呼び出しは、次のいずれかのコンテキストにのみ出現する必要があります。

  1. ifswitchwhiledo-whilefor の完全な制御式。
    switch (setjmp(env)) { // ...
  2. 関係演算子または等価演算子のオペランドの1つで、もう一方のオペランドが整数定数式であり、結果の式が ifswitchwhiledo-whilefor の完全な制御式となる場合。
    if (setjmp(env) > 0) { // ...
  3. 単項 ! 演算子のオペランドで、結果の式が ifswitchwhiledo-whilefor の完全な制御式となる場合。
    while (!setjmp(env)) { // ...
  4. 式文の完全な式(void にキャストされる場合がある)。
    setjmp(env);

setjmp が上記以外のコンテキストで出現する場合、動作は未定義です。

さらに、setjmpコルーチン内で、co_await 演算子が使用される可能性のある場所で呼び出された場合、動作は未定義です。

(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

[編集] 関連項目

指定された場所にジャンプする
(関数) [編集]
English 日本語 中文(简体) 中文(繁體)