std:: exit
From 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)
std::atexit
で登録された各関数
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)
|
完全なクリーンアップなしでプログラムを高速終了させる
(関数) |
|
(C++11)
|
std::quick_exit
呼び出し時に実行される関数を登録する
(関数) |
|
Cドキュメント
for
exit
|
|