Bar*_*rth 11 c++ exception-handling exception
我在项目中找到了一些看起来像这样的代码:
int main(int argc, char *argv[])
{
// some stuff
try {
theApp.Run();
} catch (std::exception& exc) {
cerr << exc.what() << std::endl;
exit(EXIT_FAILURE);
}
return (EXIT_SUCCESS);
}
Run Code Online (Sandbox Code Playgroud)
我不明白为什么会有例外.如果不是,则应用程序将退出并打印异常.
你认为有什么好理由在这里捕捉异常吗?
编辑:我同意打印异常错误是好的.但是,重新抛出异常不是更好吗?我觉得我们在这里吞咽它...
Ste*_*sop 16
如果未捕获异常,则标准不会定义堆栈是否已展开.因此,在某些平台上将调用析构函数,而在其他平台上,程序将立即终止.在顶层捕获可确保始终调用析构函数.
所以,如果你没有在调试器下运行,那么抓住所有东西可能是明智的:( ...)以及std :: exception.然后,即使是致命的异常,您的应用程序代码也可以使用RAII进行清理.在许多这样的情况下,您实际上并不需要清理,因为操作系统会为您完成.但是,例如,您可能希望尽可能干净地与远程服务断开连接,并且可能存在流程外部的资源,例如命名管道/互斥体,您更愿意销毁而不是泄漏.
在主要方面重新抛出异常在我看来是有限的用法,因为你已经失去了它最初抛出的上下文.我认为在调试器中捕获未捕获的异常比仅将故障记录到std :: cerr更嘈杂,因此如果有可能丢失日志记录,则重新抛出将是明智之举.
如果您希望调试器在调试模式下捕获意外情况(在发布模式下抛出异常,最终导致退出),那么还有其他方法可以做到这一点,而不是让异常未被捕获,以便调试器看到它.例如,您可以使用assert宏.当然,这对于意外和不可预测的条件没有帮助,例如,如果您在.NET上使用SEH,则会出现硬件异常.
为什么你说会打印例外?这不是C++运行时的典型行为.充其量,您可以预期其类型会被打印出来.
此外,该程序保留"故障"状态,而异常可能导致终止中止状态(即退出代码中指示的信号).
main函数中的try-catch隐藏了调试器的异常.我会说,这不好.
另一方面,客户不应该有调试器,因此捕获异常很好.所以这很好.
就个人而言,在构建调试配置时,我在制作发布版本时捕获main函数中的所有异常,并且我不这样做.
堆栈没有展开的情况的简单示例:
为什么析构函数不会在异常上被调用?
异常可能导致应用程序终止而不是展开堆栈的情况列表.
为什么析构函数不会被异常调用?
如果没有在任何级别捕获异常并且将转义main(),则允许实现调用terminate()而不是展开堆栈(是的,这也让我感到意外).
因此,我总是捕获main()中的所有异常.
int main()
{
try
{
}
catch(std::exception const& e)
{ /* LOG */
// optimally rethrow
}
catch(...) // Catch anything else.
{ /* LOG */
// optimally rethrow
}
}
Run Code Online (Sandbox Code Playgroud)
帮助在调试期间捕获问题.从std :: exception派生异常,然后在std :: exception的构造函数中粘贴断点.
| 归档时间: |
|
| 查看次数: |
5631 次 |
| 最近记录: |