我正在编写一个游戏,其中许多不同的条件都可能导致失败,例如图像或着色器无法加载,OpenGL 无法获得有效的上下文等。
在理想的世界中,我想以我认为适用于 C 的方式使用退出代码,即对于失败条件非零。但是,有一些因素会影响这一点:
atexit()
,对我来说很不幸,因为我的程序清理是通过 atexit()
中的单个 main()
注册分层处理的,我喜欢。 在我的情况下,有哪些支持和反对使用非零退出代码的论据?
最佳答案
触发注册的 atexit()
函数
与您的问题相反,即使程序尝试向主机环境返回非零终止状态,仍会调用使用 atexit()
注册的函数。调用 exit()
或返回的 main()
函数将触发使用 atexit()
注册的函数,无论给定的值如何。
例子:
#include <stdlib.h>
#include <stdio.h>
void print_stuff()
{
puts("Stuff");
}
int main()
{
atexit(print_stuff);
exit(1);
}
这将打印
Stuff
,即使返回 1
。技术细节
按照 ISO C 标准,
atexit()
中注册的函数是在调用 exit()
之后调用的。以下情况也被定义为调用 exit()
(并因此触发使用 atexit()
注册的函数):main()
返回相当于调用 exit()
。 thrd_exit()
后,调用 exit(EXIT_SUCCESS)
。 以下是调用
exit()
的可能实现定义的来源:SIGTERM
的默认信号处理程序。 set_constraint_handler_s()
之前的默认约束处理程序。 该标准提到了以下情况,其中
exit()
和对使用 atexit()
注册的函数的调用被规避:SIGABRT
或 SIGABRT
完成由注册 signal()
的函数处理。 SIGABRT
可以由 abort()
引发。 _Exit()
。 quick_exit()
。 在某些情况下,您的实现的宿主环境可能会终止程序,而不会调用使用
atexit()
注册的函数,例如在 segfault 之后。关于游戏的退出代码
您选择的退出代码对于游戏来说应该没有太大关系。是的,您不会依赖 shell 脚本来运行您的游戏并向用户报告错误。对于像 Linux 这样的系统,错误反馈可能以对话框弹出窗口、日志或 stderr 的形式更有用。
关于实时/非批处理应用程序中的 C 退出代码和 atexit(),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31864476/