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

cod*_*nix 8 c++ language-features exception

如果我执行以下操作,运行时如何确定抛出异常的类型?它是否使用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?
{
  // ..
}
Run Code Online (Sandbox Code Playgroud)

也可以看看:

如何实现C++异常处理运行时?

Joh*_*itb 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语句的表达式静态类型(前一段时间,我很高兴在GCC中解决这个问题).所以它不需要做运行时类型识别.因此g++,在throw出现的那一侧,它会移动一个std::type_info表示异常对象类型的对象,对象本身和析构函数.

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

所以,总结一下

myexceptiontype e
Run Code Online (Sandbox Code Playgroud)

const myexceptiontype *e
Run Code Online (Sandbox Code Playgroud)

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