关于catch块中catch语句的排序的问题 - 编译器特定或语言标准?

时间:2010-03-08 22:00:05

标签: c# java c++ exception-handling catch-block

我目前正在使用Visual Studio Express C ++ 2008,并且对catch块排序有一些疑问。不幸的是,我无法在互联网上找到答案,所以我向专家提出了这些问题。

我注意到除非catch(...)放在catch块的末尾,否则编译将失败,错误C2311。例如,以下内容将编译:

catch (MyException)
{
}
catch (...)
{
}

而以下情况不会:

catch (...)
{
}
catch (MyException)
{
}

一个。我是否可以问这是否是在C ++语言标准中定义的,或者这只是Microsoft编译器是严格的?

湾C#和Java是否也有相同的规则?

℃。另外,我还尝试创建基类和派生类,并在派生类的catch语句之前放置基类的catch语句。这编译没有问题。请不要有语言标准来防范这种做法吗?

3 个答案:

答案 0 :(得分:5)

根据标准,订单很重要。基本上,将捕获匹配异常的第一个catch。

a)因为catch(...)会使任何后续捕获无关紧要,标准只允许它成为最后一次捕获。

b)C#和Java有类似的规则。

c)在派生类使得派生的代码无关紧要之前捕获(通过引用或指针)。但是,该标准确实允许这个

答案 1 :(得分:3)

从C ++标准15.3 / 5“处理异常”:

  

尝试块的处理程序按外观顺序进行尝试。这使得编写永远不会执行的处理程序成为可能,例如通过在相应基类的处理程序之后放置派生类的处理程序。

     

处理程序的异常声明中的...与函数参数声明中的...类似;它指定任何异常的匹配项。如果存在,...处理程序应该是其try块的最后一个处理程序。

答案 2 :(得分:3)

所谓的默认处理程序catch(...)必须是处理程序列表中的最后一个处理程序。这确实是标准所要求的。但是,此要求特定于默认处理程序。

否则标准不会限制处理程序的顺序,这意味着通常可以创建一个处理程序来“拦截”所有异常,否则这些异常会到达列表中的其他处理程序(从而使后一个处理程序无用)。 / p>

此外,多次重复相同的catch子句(具有相同类型)是完全合法的

catch (int) {
  // ...
}
catch (int) {
  // ...
}

尽管只有第一个人有机会抓到任何东西。一个好的编译器会为这样的情况发出警告,但正式来说这不是错误。