如何在出错后结束C ++程序?

时间:2012-05-21 14:17:20

标签: c++ error-handling

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

在这段代码中,如果事情没有验证,那么解开堆栈真的没有理由或优势。我们完成了。尝试保存船只没有意义,因为它是一个非交互式代码,通过Sun Grid Engine并行运行。用户无法干预。更重要的是,这些验证失败并不真正代表特殊情况。他们是预料之中的。

那么我该如何处理这个问题呢?我不确定自己想要的一件事是每个类方法中的退出点都可能失败。这似乎无法维持。我错了吗?在这样的代码中,只要在失败点调用exit()abort(),这是否可以接受?或者我应该一直抛出一个异常回到main中的一些泛型catch语句?有什么好处?

4 个答案:

答案 0 :(得分:4)

如果程序无法正常处理错误,则终止程序是可以接受的。你可以做的事情很少:

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

使用这些功能没有任何问题,只要您了解自己在做什么,了解其他选择,并自愿选择路径。毕竟,这就是存在这些功能的原因。因此,如果您认为尝试处理错误或在发生任何其他事情时没有任何意义 - 请继续。我可能会尝试记录一些信息性消息(比如说,系统日志),然后调用_exit。如果记录失败 - 请致电abort以获得终端核心。

答案 1 :(得分:4)

抛出一个异常以便在main中被捕获然后退出意味着你的RAII资源对象被清理掉了。在大多数系统上,许多资源类型都不需要这样做。操作系统将清理内存,文件句柄等(虽然我使用的系统无法释放内存意味着它一直被分配,直到系统重启,因此在程序退出时泄漏不是一个好主意。)

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

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

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

答案 2 :(得分:2)

我建议调用全局函数

void stopProgram() {
  exit(1);
}

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

答案 3 :(得分:1)

正如您所指出的那样,在整个代码中抛出exitabort是不可维护的...此外,将来可能会有一种机制可以让您从错误,或以更优雅的方式处理错误,而不是简单地退出,并且如果您已经对此功能进行了硬编码,则撤消将非常困难。

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