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

Eng*_*eer 2 c error-handling exit-code exit atexit

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

在理想的世界中,我想以我认为用于C的方式使用退出代码,即对于故障条件非零.但是,有一些因素可以解决这个问题:

  • 在使用非零退出代码时,atexit()不会被调用,不幸的是,因为我的程序清理是通过单个atexit()注册进行分层处理的main(),我喜欢.
  • 在我看来,鉴于应用程序的性质 - 游戏具有与批处理程序不同的无限运行时间 - 实际上可能永远不会出现实际使用退出代码的情况.它不像是由Makefile调用的命令行图像转换器,它需要通过其退出代码知道程序是成功还是失败,从而确定是否继续构建.可能的情况是,如果程序在运行时出现任何问题,例如丢失文件,这是我自己解决的问题,那么就顺利进行.

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

Vel*_*tas 6

触发注册的atexit()功能

与您的问题相反,atexit()即使程序试图将非零终止状态返回到主机环境,仍会调用注册的函数.要在通话exit(),或者main()返回函数,将触发注册的功能atexit(),无论给出的价值.

例:

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

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

int main()
{
    atexit(print_stuff);
    exit(1);
}
Run Code Online (Sandbox Code Playgroud)

这将打印Stuff,即使1返回.

技术细节

由ISO C标准,在登记的功能atexit()之后被称为exit()被调用.以下情况也定义为调用exit()(因此触发注册的函数atexit()):

  1. main()返回相当于调用exit().

  2. 在最后的线程调用之后thrd_exit(),exit(EXIT_SUCCESS)被调用.

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

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

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

该标准提到了以下情况:规避了exit()对注册函数的调用atexit():

  1. 未处理SIGABRTSIGABRT完成由注册的函数处理signal().SIGABRT可以提出来abort().

  2. 打电话_Exit().

  3. 打电话quick_exit().

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

关于游戏的退出代码

您选择的退出代码对于游戏而言并不重要.是的,您不会依赖shell脚本来运行游戏并向用户报告错误.对于像Linux这样的系统,错误反馈可能以对话框弹出窗口,日志或stderr的形式更有用.