为什么我可以捕获一个对象或dynamic_cast,即使它的std :: type_info对象不同?

时间:2015-11-25 19:15:17

标签: c++ exception-handling shared-libraries typeid itanium-abi

我正在进行一项实验,并在程序和共享库中定义了同一个类,我从程序中删除了该程序,并确保程序在其dynsym表中没有类型信息对象的条目。然后我从共享库中抛出该类的对象,并尝试使用相同的类类型捕获它。

我希望linux和gcc上的实现不会捕获异常,因为程序和共享库中两个类的类型info对象都不同,因此只有运行时才能进行字符串比较,才能实现匹配。受损的班级名称。

它仍然匹配,我甚至可以对共享库中定义的类进行动态向下转换。请问有人可以解释一下这种情况下的实施方式吗?

修改

根据安腾ABI所述,观察到的行为似乎是不一致的。我在这里缺少什么?

  

因此,除了指向不完整类型的直接或间接指针外,在对那些type_info对象进行操作时,可以将相等和不等式运算符写为地址比较:当且仅当它们是相同的结构时,两个type_info结构描述相同的类型(在同一地址)。

由于两个typeinfo具有不同的地址,因此所描述的结构代表不同的类型。因此,演员表应该失败并且不应该抓住异常。

2 个答案:

答案 0 :(得分:0)

在程序和共享库中定义了同一个类,我从程序中删除了 - 祝贺违反了一个定义规则。在未定义行为的领域,任何事情都可能发生,你应该知道。

答案 1 :(得分:0)

Itanium ABI明确声明要通过 mangled name 比较类的type_info对象,这确实是你问题中的假设实现。

https://refspecs.linuxbase.org/cxxabi-1.86.html#rtti

我认为这里的基本原理是准确支持你观察到的行为。

typeinfo描述符也被定义为具有"模糊的链接",这很可爱。但是,使用的定义要求将它们放在COMDAT组中。 COMDAT组必须由链接器进行重复数据删除,至少作为静态链接的一部分。我目前无法确定是否还需要对动态链接进行重复数据删除,但这似乎是合乎逻辑的。

总而言之,你的问题的答案是,"它的处理是因为ABI的作者预见到了这种情况并确保它得到了处理"。