问题描述
如果我执行以下操作,运行时如何确定抛出的异常的类型?它使用RTTI吗?
If I do the following, how does the runtime determine the type of the thrown exception? Does it use RTTI for that?
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?
{
// ..
}
推荐答案
与其他问题中提到的问题不同,这个问题的答案可以完全通过标准来回答。这是规则
Unlike the concerns asked in that other questions, the answer to this question can be answered entirely by means of the Standard. Here are the rules
- 处理程序类型为cv T或cv T&和E和T是相同类型(忽略顶级cv限定符),或
- 处理程序类型为cv T或cv T& T是一个明确的公共基类E,或
- 处理程序类型为cv1 T * cv2,E是一个指针类型,可以转换为处理程序的类型或
- 不涉及到指向私有或受保护或模糊类的指针的标准指针转换(4.10)
- The handler is of type cv T or cv T& and E and T are the same type (ignoring the top-level cv-qualifiers), or
- the handler is of type cv T or cv T& and T is an unambiguous public base class of E, or
- the handler is of type cv1 T* cv2 and E is a pointer type that can be converted to the type of the handler by either or both of
- a standard pointer conversion (4.10) not involving conversions to pointers to private or protected or ambiguous classes
- a qualification conversion
[注意:throw-expression是整数的整数常数表达式类型,计算结果为零
不匹配指针类型的处理程序;也就是说,空指针常量转换(4.10,4.11)不要
适用。 ][Note: a throw-expression which is an integral constant expression of integer type that evaluates to zero does not match a handler of pointer type; that is, the null pointer constant conversions (4.10, 4.11) do not apply. ]
因为我不太清楚你对标准的理解程度,所以我会留下这个不明原因,请问。
As i'm not quite sure about your level of understanding of the Standard, i will leave this unexplained, and answer as you ask.
关于它是否使用RTTI - 好,所抛出的异常对象的类型是表达式的静态类型你移交给
throw
语句(前段时间,我有乐趣在GCC中找到这个)。所以它不需要做运行时类型识别。因此,在g ++
的情况下,在throw
出现的一侧,它移交std :: type_info
表示异常对象类型的对象,对象本身和析构函数。With regard to whether it uses RTTI or not - well, the type of the exception object being thrown is the static type of the expression you hand over to the
throw
statement (some time ago, i had fun figuring this out in GCC). So it does not need to do runtime type identification. So it happens, withg++
, that at the side where thethrow
appears, it hands over astd::type_info
object representing the type of the exception object, the object itself and a destructor function.然后抛出它,并且搜索框架以寻找匹配的处理程序。使用在大表中找到的信息(位于
.eh_frame
),并使用返回地址,它看起来什么函数负责下一个处理。该函数将安装一个个性程序,以确定它是否可以处理异常。这个整个过程在由@PaV链接的Itanium C ++ ABI(由G ++实现)中描述(当然更详细)。It's then thrown and frames are searched for a matching handler. Using information found in big tables (located in a section called
.eh_frame
), and using the return address, it looks what function is responsible for the next handling. The function will have a personality routine installed that figures out whether it can handle the exception or not. This whole procedure is described (and in more detail, of course) in the Itanium C++ ABI (implemented by G++) linked by @PaV.因此,总结
myexceptiontype e
和
const myexceptiontype *e
当然不要处理相同的类型。
Do not handle the same type, of course.
这篇关于C ++运行时如何确定抛出的异常的类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!