お詫びと訂正
初投稿時は15秒で目を通せそうな内容でしたが(当社比)、現状15秒では無理そうです。
はじめに
@celluloce に記事投稿の少し前にはなしたメモをせっかくだから上げておくだけです。
なお話がややこしくなるのでsignalとの絡みは割愛します。
main関数からのreturn文
- main関数のスコープにある変数やstatic storageな記憶期間の変数のデストラクタが呼ばれる(C++)
- というかautomatic storageな記憶期間の変数のデストラクタを呼んだあと
exit
を呼ぶ - なので、
atexit
で登録された関数が呼ばれる
atexitで登録した関数が呼ばれる
#include <iostream>
#include <cstdlib>
void on_exit()
{
std::cout << "on_exit called" << std::endl;
}
int main(){
std::atexit(on_exit);
return 0;
}
実行結果
on_exit called
exit
呼び出し
-
atexit
で登録された関数を呼び出してから終了する - static storageな記憶期間の変数のデストラクタが呼ばれる(C++)
- つまりC++では概ね
quick_exit
を使うべき(C++)
quick_exit
呼び出し
-
at_quick_exit
で登録された関数を呼び出してから終了する - C11/C++11から
- 主にマルチスレッドプログラムの同期をキャンセルしてプログラムを終了させるときに。
- Cストリームのバッファはフラッシュされない。
- 一切のデストラクタを呼びたくないときもこっち(C++)
_Exit
呼び出し
- 基本
quick_exit
と同じ。というかquick_exit
がat_quick_exit
で登録された関数を呼び出したあとにこれに処理を投げるので当たり前だけど
abort
呼び出し
- 基本
_Exit
と同じ。がしかし、これは異常終了を通知する。 -
at_quick_exit
で登録された関数を呼び出さないと思うんだけど、C11規格書(N1570)やC++17規格書(N4659)を読んでも該当文章が見つからない・・・
まとめ
main関数からのreturn文 | exit | quick_exit | _Exit | abort | |
---|---|---|---|---|---|
atexit で登録された関数の呼び出し |
○ | ○ | ✕ | ✕ | ✕ |
at_quick_exit で登録された関数の呼び出し |
✕ | ✕ | ○ | ✕ | ? |
Cストリームバッファのフラッシュなど | ○ | ○ | 処理系定義 | 処理系定義 | 処理系定義 |
static storageな期間をもつ変数の破棄 | ○ | ○ | ✕ | ✕ | ✕ |
thread local storageな期間をもつ変数の破棄 | ○ | ○ | ✕ | ✕ | ✕ |
automatic storageな期間をもつ変数の破棄 | ○ | ✕ | ✕ | ✕ | ✕ |
「Cストリームバッファのフラッシュなど 」というのは、
- Cストリームバッファのフラッシュする
- 開いているすべてのCストリームを閉じる
-
tmpfile
関数で作られた一時ファイルの除去
の3点セットのこと。
ref
storageについては
C++のメモリーの話とストレージの有効期間の話をしようか
デストラクターとは?という人は
C++入門者に贈るclass入門とclass/structキーワードの使い分け