std::exit
ja.cppreference.net より
| ヘッダ <cstdlib>
|
||
void exit( int exit_code );
|
で定義 (C++11未満) | |
[[noreturn]] void exit( int exit_code );
|
(C++11以上) | |
プログラムの正常終了を引き起こします。
いくつかのクリーンアップ手順が実行されます:
|
1) 静的記憶域期間を持つオブジェクトが破棄され、std::atexit の呼び出しによって登録された関数が呼び出されます:
a) 静的記憶域期間を持つ非ローカルオブジェクトは、そのコンストラクタの完了の逆順で破棄されます。
b) std::atexit に登録された関数は、登録の逆順で呼び出されます。ただし、関数は、その登録時に既に呼び出されていた以前に登録された関数がすべて呼び出された後に呼び出されます。
c)
f が std::atexit に登録された各関数、および静的記憶域期間を持つ各非ローカルオブジェクト obj について、
d) 静的記憶域期間を持つ各ローカルオブジェクト obj について、obj は、obj のコンストラクタの完了時に std::atexit に obj のデストラクタを呼び出す関数が登録されたかのように破棄されます。
|
(C++11未満) |
|
1) 現在のスレッドに関連付けられたスレッドローカル 記憶域期間 を持つオブジェクトのデストラクタ、静的記憶域期間を持つオブジェクトのデストラクタ、および std::atexit に登録された関数は、以下の保証を維持しながら同時に実行されます:
a) スレッドローカルオブジェクトの最後のデストラクタは、静的オブジェクトの最初のデストラクタよりも前に sequenced-before されます。
b) スレッドローカルまたは静的オブジェクト A のコンストラクタまたは 動的初期化 の完了がスレッドローカルまたは静的オブジェクト B よりも前に sequenced-before される場合、B の破棄の完了は A の破棄の開始よりも前に sequenced-before されます。
c) 静的オブジェクト A の初期化の完了がある関数 F に対する std::atexit の呼び出しよりも前に sequenced-before される場合、終了時の F の呼び出しは A の破棄の開始よりも前に sequenced-before されます。
d) ある関数 F に対する std::atexit の呼び出しが静的オブジェクト A の初期化の完了よりも前に sequenced-before される場合、A の破棄の開始は終了時の F の呼び出しよりも前に sequenced-before されます。
e) ある関数 F1 に対する std::atexit の呼び出しがある関数 F2 に対する std::atexit の呼び出しよりも前に sequenced-before される場合、終了時の F2 の呼び出しは F1 の呼び出しよりも前に sequenced-before されます。
|
(C++11以上) |
- 上記において、
atexitに登録された関数または静的/スレッドローカルオブジェクトのデストラクタが例外を投げた場合、std::terminate が呼び出されます。- コンパイラがオブジェクトの動的初期化を 非ローカル初期化 の静的初期化フェーズに繰り上げることを選択した場合、破棄の順序はその動的初期化があったかのように尊重されます。
- 関数ローカル(ブロックスコープ)静的オブジェクトが破棄され、その後その関数が別の静的オブジェクトのデストラクタから呼び出され、制御フローがそのオブジェクトの定義を通過する場合(またはポインタや参照を介して間接的に使用される場合)、動作は未定義です。
- 関数ローカル(ブロックスコープ)静的オブジェクトがクラスまたは配列のサブオブジェクトの構築中に初期化された場合、そのクラスのすべてのサブオブジェクトまたはその配列のすべての要素が破棄された後にのみ破棄されます。
2) すべての C ストリームがフラッシュされ、閉じられます。
3) std::tmpfile によって作成されたファイルが削除されます。
4) 制御はホスト環境に返されます。
exit_code が 0 または EXIT_SUCCESS の場合、正常終了を示す処理系定義のステータスが返されます。exit_code が EXIT_FAILURE の場合、異常終了を示す処理系定義のステータスが返されます。その他の場合、処理系定義のステータス値が返されます。スタックは巻き戻されません: 自動 記憶域期間 を持つ変数のデストラクタは呼び出されません。
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)
|
完全なクリーンアップなしでプログラムを高速終了させる
(関数) |
|
(C++11)
|
std::quick_exit
呼び出し時に実行される関数を登録する
(関数) |
|
Cドキュメント
for
exit
|
|