C ++运行时如何确定抛出异常的类型?

时间:2009-06-14 17:27:15

标签: c++ exception language-features

如果我执行以下操作,运行时如何确定抛出异常的类型?它是否使用RTTI?

try
{
  dostuff(); // throws something
}
catch(int e)
{
  // ..
}
catch (const char * e)
{
  // ..
}
catch (const myexceptiontype * e)
{
  // ..
}
catch (myexceptiontype e) // is this the same as the previous handler?
{
  // ..
}

另见:

  

How is the C++ exception handling runtime implemented?

2 个答案:

答案 0 :(得分:7)

与其他问题中提出的问题不同,这个问题的答案可以完全通过标准来回答。这是规则

  

处理程序是E类型的异常对象的匹配,如果

     
      
  • 处理程序的类型为cv T或cv T&和E和T是相同的类型(忽略顶级cv限定符),或
  •   
  • 处理程序的类型为cv T或cv T&和T是E的明确的公共基类,或
  •   
  • 处理程序的类型为cv1 T * cv2,E是一种指针类型,可以通过其中一个或两个转换为处理程序的类型      
        
    • 标准指针转换(4.10),不涉及转换为指向私有或受保护或模糊类的指针
    •   
    • 资格转换
    •   
  •   
     

[注意:一个throw-expression,它是整数类型的整数常量表达式,其计算结果为零   与指针类型的处理程序不匹配;也就是说,空指针常量转换(4.10,4.11)不会   应用。 ]

由于我不太确定你对标准的理解程度,我会将此解释不明,并按你的要求回答。

关于它是否使用RTTI - 好吧,抛出的异常对象的类型是你移交给throw语句的表达式的静态类型很久以前,我很高兴在海湾合作委员会中搞清楚这一点。所以它不需要做运行时类型识别。因此,使用g++,在throw出现的那一侧,它会移交一个std::type_info对象,表示异常对象的类型,对象本身和析构函数。

然后抛出并搜索帧以寻找匹配的处理程序。使用大表(位于名为.eh_frame的部分)中找到的信息,并使用返回地址,它查看哪个函数负责下一次处理。该函数将安装一个个性例程,以确定它是否可以处理异常。整个过程在由@PaV链接的Itanium C ++ ABI(由G ++实现)中描述(当然更详细)。

所以,总结

myexceptiontype e

const myexceptiontype *e

当然,不要处理相同的类型。

答案 1 :(得分:4)

没有实施规范。实现必须遵循标准,并且对其实现方式没有限制。并且有一个以上的实现,即使对于一个编译器也是如此。

您可以在此处阅读其中一个此类实现的示例:

Itanium C++ ABI: Exception Handling