exit()
Open Groupの基本仕様(さまざまな問題)の機能説明で、以下を読みました。
この
exit()
関数は、最初にatexit()に登録されているすべての関数を登録の逆順に呼び出す必要があります。登録時に呼び出された以前に登録された関数の後に関数が呼び出されない限り。
確かに私のせいですが、太字を理解できません(そして文法構造も認識できません!)。他の人にこの文の意味を変えて説明してもらうように頼むことができますか?例があるかもしれません。
答え1
仕様のこの部分は、他の終了ハンドラで登録された関数を扱います。考える
#include <stdio.h>
#include <stdlib.h>
void func1(void) {
puts("func1");
}
void func2(void) {
puts("func2");
}
void func4(void);
void func3(void) {
atexit(func4);
puts("func3");
}
void func4(void) {
puts("func4");
}
int main(int argc, char **argv) {
atexit(func1);
atexit(func2);
atexit(func3);
}
これらfunc1
の関数は数値順に登録されていfunc2
ます。登録時にすでに呼び出されているため、ハンドラの実行順序では考慮されなくなりました。func3
main
func4
func3
main
func3
func4
$ make exit
cc exit.c -o exit
$ ./exit
func3
func4
func2
func1
強調表示された部分がない場合は、厳密な解釈に従って以前にfunc4
呼び出す必要があるかfunc3
(不可能)func3
後に呼び出す必要があるか(再度)、func4
終了処理が開始されると、ハンドラを登録できなくなることが示唆されます(実行を保存するため)。注文する)。
答え2
プログラム呼び出し
exit(3)
(または関数から返されたmain()
)の後、すべての関数はすでに登録されたものはatexit(3)
登録の逆順で呼び出されます。しかし、登録された関数
atexit(3)
(と呼ぶfoo()
)自体を呼び出してatexit(3)
登録することができます。その他の機能(bar()
)にプッシュされます。フロントリストにあり、すぐ後ろに呼び出されますfoo()
。
登録されているにもかかわらず、bar()
その後も引き続き呼び出されます。foo()
後ろに foo()
これは、「すべての関数が登録された逆順で呼び出される」という「規則」の例外です。
お役に立てば幸いです。