为什么不使用function-try-block声明main()?

时间:2017-10-16 19:53:27

标签: c++ exception-handling

a few SO posts关于使用 function-try-block语法声明main()是否为valid syntax,以及共识似乎是完全有效的。这让我想知道......有什么理由(性能,样式,线程同步,多线程)为什么一个不会使用main()的这种语法作为捕获任何未处理的一般规则在任何地方更优雅的例外?

显然,理想情况下不存在未处理的异常,但它们会发生,我认为提供比特定于操作系统的默认处理程序更具信息性的内容会更好。例如,在我的情况下,我想向用户提供一个支持电子邮件地址,以便他们报告崩溃并让我的程序向我的基于云的崩溃日志提交日志。

5 个答案:

答案 0 :(得分:2)

  

例如,在我的情况下,我想向用户提供支持电子邮件地址

那么,你打算如何在没有面向用户界面的服务器上做到这一点?

实际上,即使在使用面向用户的组件的进程中,如果你无法在catch块中告诉他们他们的状态是什么,你将如何做到这一点?重新进入?

并且,对于那些您无法向用户显示任何有用信息(或者首先没有"用户"的概念)的流程,您会做什么?在catch块中,哪个块会优于默认terminate

至于

  

...比特定于操作系统的默认处理程序更具信息性......

很多OS'默认行为是将流程执行状态的完整快照(在未处理的异常被抛出时)保存到文件以进行调试。作为开发人员,我无法想到许多更多提供信息的默认行为。

不可否认,作为桌面应用的最终用户,我更喜欢更优秀的东西,但这只是C ++程序的一小部分。

答案 1 :(得分:0)

如果您碰巧有一个要在catch块中访问的变量,则需要花括号来提供可见性。但即便如此,也可以使用嵌套的try / catch ...

来处理

答案 2 :(得分:0)

如果你捕获(否则)未被捕获的对象,你将无法通过检查堆栈跟踪来弄清楚执行是如何达到抛出的,因为当执行异常处理程序时,堆栈已经被展开。

如果让意外的异常未被捕获,您可以检查终止处理程序中的堆栈跟踪 - 这不是标准的保证,但这不是因为没有标准的方法来检查堆栈跟踪(在C ++中)。您可以在程序中使用特定于平台的API,也可以使用外部调试程序进行检查。

因此,例如在您的情况下,不捕获异常的优点是您可以将堆栈跟踪附加到您要提交的日志条目。

此外,有些情况下catch块无法处理异常。例如,当您从因抛出异常而执行的析构函数中抛出时。所以,要处理这些"无法捕获的"例外情况,无论如何都需要终止处理程序,因此在未捕获异常的情况下复制功能几乎没有优势。

至于用于捕获异常的语法,没有区别。函数try块不同的情况是构造函数,它允许捕获子对象构造函数抛出的异常。

答案 3 :(得分:0)

您可以轻松转换

int main() try {
   // The real code of main
}
catch (...)
{
}

int realMain()
{
   // The real code of main
}

int main()
{
   try
   {
      return realMain();
   }
   catch ( ... )
   {
   }
}

不失功能/行为。

我猜你是否使用第一个版本或第二个版本是团队编码实践的问题。从编译器和运行时的角度来看,我没有看到任何语义差异。

答案 4 :(得分:0)

  

为什么人们不会将此语法用于main()作为捕获的一般规则   任何更优雅的未处理异常?

  1. 与C的兼容性。
  2. 有时候没有办法更优雅地处理未处理的异常。
  3.   

    显然,理想情况下,不会有未处理的例外情况,但它们   发生了,我认为提供更多信息更好   比特定于操作系统的默认处理程序。例如,就我而言,我是   喜欢向用户提供支持电子邮件地址,以便他们报告   崩溃并让我的程序向我的基于云的崩溃提交日志   日志中。

    如果发生意外异常,您无法确定是否可以正确处理。如果您的示例中存在网络错误异常,您打算怎么做?并尝试发送电子邮件导致另一个例外?如果您无法确定数据是否已损坏,并且在此错误后无法确定程序是否可以正常运行,则可能会出现其他错误。因此,如果您不知道发生了什么错误,最好让您的程序崩溃。 你可以实现另一个观察者"检查进程是否正在运行以及是否已崩溃的服务可以使用日志和核心转储向您的用户发送电子邮件。