Namespaces
Variants

std:: exit

From cppreference.net
Utilities library
定義先ヘッダ <cstdlib>
void exit ( int exit_code ) ;
(C++11まで)
[ [ noreturn ] ] void exit ( int exit_code ) ;
(C++11以降)

通常のプログラム終了を引き起こします。

いくつかのクリーンアップ手順が実行されます:

1) 静的ストレージ期間を持つオブジェクトが破棄され、 std::atexit を呼び出して登録された関数が呼び出される:
a) 静的ストレージ期間を持つ非ローカルオブジェクトは、コンストラクタの完了順序と逆順で破棄される。
b) std::atexit で登録された関数は、登録順と逆順で呼び出される。ただし、登録時に既に呼び出されていた以前に登録された関数の後に関数が呼び出される。
c) std::atexit で登録された各関数 f と静的ストレージ期間を持つ各非ローカルオブジェクト obj について、
  • f obj の初期化前に登録された場合、 f obj の破棄後にのみ呼び出される;
  • f obj の初期化後に登録された場合、 f obj の破棄前にのみ呼び出される。
d) 静的ストレージ期間を持つ各ローカルオブジェクト obj について、 obj は、 obj のコンストラクタ完了時に obj のデストラクタを呼び出す関数が std::atexit に登録されたかのように破棄される。
(C++11以前)
1) 現在のスレッドに関連付けられたスレッドローカル ストレージ期間 を持つオブジェクトのデストラクタ、静的ストレージ期間を持つオブジェクトのデストラクタ、および std::atexit に登録された関数は、以下の保証を維持しながら並行して実行される:
a) スレッドローカルオブジェクトの最後のデストラクタは、静的オブジェクトの最初のデストラクタに対して シーケンスされる
b) スレッドローカルまたは静的オブジェクトAのコンストラクタまたは 動的初期化 の完了がスレッドローカルまたは静的オブジェクトBに対してシーケンスされていた場合、Bの破棄の完了はAの破棄の開始に対してシーケンスされる。
c) 静的オブジェクトAの初期化の完了が何らかの関数Fに対する std::atexit の呼び出しに対してシーケンスされていた場合、終了処理中のFの呼び出しはAの破棄の開始に対してシーケンスされる。
d) 何らかの関数Fに対する std::atexit の呼び出しが静的オブジェクトAの初期化完了に対してシーケンスされていた場合、Aの破棄の開始は終了処理中のFの呼び出しに対してシーケンスされる。
e) 何らかの関数F1に対する std::atexit の呼び出しが何らかの関数F2に対する std::atexit の呼び出しに対してシーケンスされていた場合、終了処理中のF2の呼び出しはF1の呼び出しに対してシーケンスされる。
(C++11以降)
  • 上記において、
  • atexit で登録された関数、または静的/スレッドローカルオブジェクトのデストラクタが例外をスローした場合、 std::terminate が呼び出される。
  • コンパイラがオブジェクトの動的初期化を 非ローカル初期化 の静的初期化フェーズに昇格させることを選択した場合、破棄の順序はその動的初期化が行われるはずだった順序を尊重する。
  • 関数ローカル(ブロックスコープ)静的オブジェクトが破棄された後、別の静的オブジェクトのデストラクタからその関数が呼び出され、制御フローがそのオブジェクトの定義を通過する場合(またはポインタや参照を介して間接的に使用される場合)、動作は未定義である。
  • 関数ローカル(ブロックスコープ)静的オブジェクトがクラスのサブオブジェクトまたは配列の構築中に初期化された場合、そのクラスのすべてのサブオブジェクトまたはその配列のすべての要素が破棄された後にのみ破棄される。
2) すべてのCストリームはフラッシュされ、クローズされます。
3) std::tmpfile によって作成されたファイルは削除されます。
4) 制御がホスト環境に返されます。 exit_code 0 または EXIT_SUCCESS の場合、正常終了を示す実装定義のステータスが返されます。 exit_code EXIT_FAILURE の場合、異常終了を示す実装定義のステータスが返されます。それ以外の場合、実装定義のステータス値が返されます。

スタックは巻き戻されません:自動 storage duration を持つ変数のデストラクタは呼び出されません。

目次

main関数との関係

main関数 からの戻りは、 return 文によるものか、関数の終端に到達することによるものであれ、通常の関数終了処理(自動 ストレージ期間 を持つ変数のデストラクタ呼び出し)を実行した後、 std::exit を実行し、return文の引数(または暗黙的な戻りが使用された場合は 0 )を exit_code として渡します。

パラメータ

exit_code - プログラムの終了ステータス

戻り値

(なし)

#include <cstdlib>
#include <iostream>
struct Static
{
    ~Static() 
    {
        std::cout << "Static destructor\n";
    }
};
struct Local
{
    ~Local() 
    {
        std::cout << "Local destructor\n";
    }
};
Static static_variable; // このオブジェクトのデストラクタは*呼び出される*
void atexit_handler()
{
    std::cout << "atexit handler\n";
}
int main()
{
    Local local_variable; // このオブジェクトのデストラクタは呼び出され*ない*
    const int result = std::atexit(atexit_handler); // ハンドラは呼び出される
    if (result != 0)
    {
        std::cerr << "atexit registration failed\n";
        return EXIT_FAILURE;
    }
    std::cout << "test\n";
    std::exit(EXIT_FAILURE);
    std::cout << "this line will *not* be executed\n";
}

出力:

test
atexit handler
Static destructor

欠陥報告

以下の動作変更の欠陥報告書は、以前に公開されたC++規格に対して遡及的に適用されました。

DR 適用対象 公開時の動作 正しい動作
LWG 3 C++98 クリーンアップ中、(1) 関数が
std::atexit に登録されている場合、または (2) 静的ローカルオブジェクトが初期化されている場合の動作が不明確であった
明確化された

関連項目

異常終了を引き起こす(クリーンアップなし)
(関数)
std::exit() 呼び出し時に実行される関数を登録する
(関数)
(C++11)
完全なクリーンアップなしでプログラムを高速終了させる
(関数)
std::quick_exit 呼び出し時に実行される関数を登録する
(関数)