在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
frommain
和func4
from 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()
,这是“规则”的一个例外,即“所有函数都按照其注册的相反顺序调用”。
希望这可以帮助。