实时/非批处理应用程序中的 C 退出代码和 atexit()

C exit codes and atexit() in a realtime / non-batch app

我正在编写一个游戏,其中许多不同的条件都可能导致失败,例如图像或着色器无法加载、OpenGL 无法获得有效的上下文等。

在理想情况下,我想以我认为适用于 C 的方式使用退出代码,即对于失败情况非零。但是,有一些因素对此有影响:

在我的情况下,可以提出哪些支持和反对使用非零退出代码的论据?

触发注册的atexit()个函数

与您的问题相反,即使程序尝试 return 主机环境的非零终止状态,仍会调用使用 atexit() 注册的函数。调用 exit()main() 函数 returning,将触发使用 atexit() 注册的函数,无论给定值如何。

示例:

#include <stdlib.h>
#include <stdio.h>

void print_stuff(void)
{
    puts("Stuff");
}

int main(void)
{
    atexit(print_stuff);
    exit(1);
}

这将打印 Stuff,即使 1 是 returned。

技术细节

根据ISO C标准,在atexit()中注册的函数在调用exit()之后调用。以下情况也被定义为调用exit()(并因此触发用atexit()注册的函数):

  1. main() returning 相当于调用 exit().

  2. 最后一个线程调用thrd_exit()后,调用exit(EXIT_SUCCESS)

以下是调用 exit() 的可能实现定义来源:

  1. SIGTERM 的默认信号处理程序。

  2. 使用前的默认约束处理程序set_constraint_handler_s()

标准提到了以下情况,其中 exit() 和对使用 atexit() 注册的函数的调用被规避:

  1. 一个未处理的 SIGABRT 或一个 SIGABRT 已完成由在 signal() 注册的函数处理。 SIGABRT 可以通过 abort().

    提高
  2. 正在调用 _Exit()

  3. 正在调用 quick_exit()

在某些情况下,您的实现的宿主环境可能会在不调用 atexit() 注册的函数的情况下终止程序,例如在 segfault.

之后

关于游戏的退出代码

您选择的退出代码对于游戏来说应该无关紧要。是的,您不会依赖 shell 脚本来 运行 您的游戏并向用户报告错误。对于像 Linux.

这样的系统,错误反馈可能以对话框弹出窗口、日志或标准错误的形式更有用。