捕获主要(...)中的异常是否有意义?

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,则会出现硬件异常.


Mar*_*wis 6

为什么你说会打印例外?这不是C++运行时的典型行为.充其量,您可以预期其类型会被打印出来.

此外,该程序保留"故障"状态,而异常可能导致终止中止状态(即退出代码中指示的信号).


Pau*_*ius 6

main函数中的try-catch隐藏了调试器的异常.我会说,这不好.

另一方面,客户不应该有调试器,因此捕获异常很好.所以这很好.

就个人而言,在构建调试配置时,我在制作发布版本时捕获main函数中的所有异常,并且我不这样做.


Mar*_*ork 5

堆栈没有展开的情况的简单示例:
为什么析构函数不会在异常上被调用?

异常可能导致应用程序终止而不是展开堆栈的情况列表.
为什么析构函数不会被异常调用?

如果没有在任何级别捕获异常并且将转义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的构造函数中粘贴断点.