错误后如何结束C++程序
How to end a C++ program after error?
我正在重构一个旧代码,我想解决的一件事是处理错误的方式。我很清楚异常以及它们是如何工作的,但我不完全确定它们是我试图处理的情况的最佳解决方案。
在此代码中,如果事情没有验证,则实际上没有理由或优势来展开堆栈。大功告成。试图拯救飞船是没有意义的,因为它是通过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);
}
稍后您可以更改它的行为,因此它是可维护的。
正如您所指出的,在整个代码中抛出exit
或abort
是不可维护的......此外,将来可能会有一种机制允许您从错误中恢复,或者以比简单地退出更优雅的方式处理错误,如果您已经硬编码了此功能,那么将很难撤消。
此时,抛出main()
捕获的异常是最好的选择,如果您在允许从错误中恢复或以不同方式处理错误的不同方案下运行代码,这也将为您提供将来的灵活性。 此外,如果您决定添加更多调试支持等,抛出异常可能会有所帮助,因为它将为您提供实现日志记录功能的位置,并在您决定让程序退出之前记录软件中隔离和可维护点的程序状态。
- 为什么在这个代码结束循环中没有得到结束
- 试图对缓存进行跨步测试,但程序并没有结束
- 当调用switch语句中的函数时(即使函数不包含循环),似乎是永不结束的循环的问题
- 为什么擦除方法会影响结束方法
- 根据用户输入用字母填充矢量,并将"开始"和"结束"放在四肢
- 删除映射和分割错误中的一个过去结束元素
- 如何使用 SFML 在贪吃蛇游戏中定义游戏结束?
- 为什么我的两个 cin 语句没有在程序结束时运行?
- 在函数结束后使用指向变量的指针是否安全?
- C ++尝试并捕获未结束的程序
- 为什么我的程序在输入某个形状的面积的测量值后没有结束?
- 取消引用结束指针到数组类型的一个
- 如何在 c++ 中确定一条指令(以字节为单位)在哪里结束,另一条指令从哪里开始?
- 结束另一个线程中使用的对象的生存期
- 全局向量导致 C++ 程序结束时出现段错误
- 程序显示以退出代码 0; 结束
- 如何显示函数开始、结束行和函数体?
- C++ 从具有开始位置和结束位置的列表中删除
- 使用 shared_ptr 在中断时结束多线程循环
- 文件追加的方式是,它在每次保存C++后结束行