Namespaces
Variants

std:: set_terminate

From cppreference.net
定義済みヘッダー <exception>
(C++11まで)
(C++11以降)

f を新たなグローバル終了ハンドラ関数とし、以前に設定されていた std::terminate_handler を返す。 f は呼び出し元に戻らずプログラムの実行を終了させなければならず、そうでない場合の動作は未定義である。

この関数はスレッドセーフです。 std::set_terminate へのすべての呼び出しは、 synchronizes-with std::memory_order を参照)その後の std::set_terminate および std::get_terminate の呼び出しと同期します。

(C++11以降)

目次

パラメータ

f - std::terminate_handler 型の関数へのポインタ、またはヌルポインタ

戻り値

以前にインストールされていた終了ハンドラ、または何もインストールされていなかった場合はnullポインタ値。

#include <cstdlib>
#include <exception>
#include <iostream>
int main()
{
    std::set_terminate([]()
    {
        std::cout << "Unhandled exception\n" << std::flush;
        std::abort();
    });
    throw 1;
}

出力例:

Unhandled exception
bash: line 7:  7743 Aborted                 (core dumped) ./a.out

終了ハンドラは起動されたスレッドに対しても機能するため、スレッド関数を try / catch ブロックでラップする代替手段として使用できます。以下の例では、例外がハンドルされていないため、 std::terminate が呼び出されます。

#include <iostream>
#include <thread>
void run()
{
    throw std::runtime_error("Thread failure");
}
int main()
{
    try
    {
        std::thread t{run};
        t.join();
        return EXIT_SUCCESS;
    }
    catch (const std::exception& ex)
    {
        std::cerr << "Exception: " << ex.what() << '\n';
    }
    catch (...)
    {
        std::cerr << "Unknown exception caught\n";
    }
    return EXIT_FAILURE;
}

出力例:

terminate called after throwing an instance of 'std::runtime_error'
  what():  Thread failure
Aborted (core dumped)

terminateハンドラの導入により、非メインスレッドからの例外を分析し、適切に終了を実行できるようになりました。

#include <iostream>
#include <thread>
class foo
{
public:
    foo() { std::cerr << "foo::foo()\n"; }
    ~foo() { std::cerr << "foo::~foo()\n"; }
};
// 静的オブジェクト、終了時にデストラクタが呼ばれることを期待
foo f;
void run()
{
    throw std::runtime_error("Thread failure");
}
int main()
{
    std::set_terminate([]()
    {
        try
        {
            std::exception_ptr eptr{std::current_exception()};
            if (eptr)
            {
                std::rethrow_exception(eptr);
            }
            else
            {
                std::cerr << "Exiting without exception\n";
            }
        }
        catch (const std::exception& ex)
        {
            std::cerr << "Exception: " << ex.what() << '\n';
        }
        catch (...)
        {
            std::cerr << "Unknown exception caught\n";
        }
        std::exit(EXIT_FAILURE);
    });
    std::thread t{run};
    t.join();
}

出力:

foo::foo()
Exception: Thread failure
foo::~foo()

関連項目

例外処理が失敗したときに呼び出される関数
(関数)
現在のterminate_handlerを取得する
(関数)
std::terminate によって呼び出される関数の型
(typedef)