Namespaces
Variants

setjmp

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

汎用ユーティリティ
関係演算子 (C++20で非推奨)
整数比較関数
(C++20)(C++20)(C++20)    
(C++20)
swap と 型操作
(C++14)
(C++11)
(C++11)
(C++11)
(C++17)
共通語彙型
(C++11)
(C++17)
(C++17)
(C++17)
(C++11)
(C++17)
(C++23)



 
 
ヘッダ <csetjmp>
#define setjmp(env) /* implementation-defined */

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

setjmp の呼び出しは、以下のコンテキストのいずれかでのみ現れなければなりません:

  1. if、switch、while、do-while、for の制御式全体。
    switch (setjmp(env)) { // ...
    
  2. 関係演算子または等価演算子の一方の被演算子であり、もう一方の被演算子が整数定数式であり、結果の式が if、switch、while、do-while、for の制御式全体となるもの。
    if (setjmp(env) > 0) { // ...
    
  3. 単項  ! 演算子の被演算子であり、結果の式が if、switch、while、do-while、for の制御式全体となるもの。
    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); // エラーハンドラへジャンプ
    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("{}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))
    {
        // ソルバーのエラーハンドラ
        std::cout << "実数解なし\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;
}

出力:

1x² + -3x + 2 = 0 を解いています...
x₁ = 1, x₂ = 2
2x² + -3x + -2 = 0 を解いています...
x₁ = -0.5, x₂ = 2
1x² + 2x + 3 = 0 を解いています...
実数解なし

関連項目

指定された場所にジャンプする
(関数)