错误后如何结束C++程序

How to end a C++ program after error?

本文关键字:结束 C++ 程序 何结束 错误      更新时间:2023-10-16

我正在重构一个旧代码,我想解决的一件事是处理错误的方式。我很清楚异常以及它们是如何工作的,但我不完全确定它们是我试图处理的情况的最佳解决方案。

在此代码中,如果事情没有验证,则实际上没有理由或优势来展开堆栈。大功告成。试图拯救飞船是没有意义的,因为它是通过Sun Grid Engine并行运行的非交互式代码。用户无法干预。更重要的是,这些验证失败并不真正代表特殊情况。他们是意料之中的。

那么我该如何最好地处理这个问题呢?我不确定我想要的一件事是每个可能失败的类方法中的退出点。这似乎是无法维护的。我错了吗?在这样的代码中,在故障点调用exit()abort()是可以接受的做法吗?还是我应该将异常一直抛回main中的某个通用catch语句?优势是什么?

抛出异常以在 main 中捕获然后退出意味着您的 RAII 资源对象将被清理。在大多数系统上,许多资源类型都不需要这样做。操作系统将清理内存、文件句柄等(尽管我使用过的系统无法释放内存意味着它在系统重新启动之前一直处于分配状态,因此在程序退出时泄漏不是一个好主意。

但是,您可能希望完全释放其他资源类型,例如网络或数据库连接,或者您正在驾驶并需要安全关闭的机械设备。如果应用程序使用了很多这样的东西,那么您可能更愿意抛出一个异常来将堆栈展开回 main,然后退出。

因此,适当的退出方法取决于应用程序。如果应用程序知道它是安全的,那么调用 _Exit((、abort((、exit(( 或 quickexit(( 可能是完全合理的。(库代码不应该调用这些,因为显然库不知道它是否对每个将使用该库的应用程序都是安全的。如果在应用程序退出之前必须执行一些关键清理,但您知道它是有限的,那么应用程序可以通过 atexit(( 或 at_quick_exit(( 注册该清理代码。

所以基本上决定你需要清理什么,记录它,实现它,并尝试确保它经过测试。

如果程序无法正常处理错误,则终止程序是可以接受的。您可以执行以下几项操作:

  • 如果需要核心转储,请调用abort()
  • 如果要有机会运行向atexit()注册的那些例程(最有可能调用全局C++对象的析构函数(,请调用exit()
  • 调用 _exit() 以立即终止进程。

使用这些功能并没有错,只要你了解你在做什么,知道你的其他选择,并自愿选择这条路。毕竟,这就是这些功能存在的原因。因此,如果您认为在错误发生时尝试处理错误或执行任何其他操作没有任何意义 - 请继续。我可能会做的是尝试记录一些信息性消息(例如,到系统日志(,然后调用_exit。如果日志记录失败 - 调用 abort 以获取沿终止的核心。

我建议调用全局函数

void stopProgram() {
  exit(1);
}

稍后您可以更改它的行为,因此它是可维护的。

正如您所指出的,在整个代码中抛出exitabort是不可维护的......此外,将来可能会有一种机制允许您从错误中恢复,或者以比简单地退出更优雅的方式处理错误,如果您已经硬编码了此功能,那么将很难撤消。

此时,抛出main()捕获的异常是最好的选择,如果您在允许从错误中恢复或以不同方式处理错误的不同方案下运行代码,这也将为您提供将来的灵活性。 此外,如果您决定添加更多调试支持等,抛出异常可能会有所帮助,因为它将为您提供实现日志记录功能的位置,并在您决定让程序退出之前记录软件中隔离和可维护点的程序状态。