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

Why can I catch an object or dynamic_cast even if its std::type_info object is different?

本文关键字:std type 对象 info 我可以 一个对象 cast dynamic 为什么      更新时间:2023-10-16

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

我预计linux和gcc上的实现不会捕捉到异常,因为程序和共享库中两个类的类型信息对象都不同,因此只有运行时对损坏的类名进行字符串比较,才可能匹配。

它仍然匹配,我甚至可以对共享库中定义的类进行动态下转换。有人能解释一下在这种情况下实现是如何工作的吗?

编辑

根据安腾ABI的状态,观察到的行为似乎是不一致的。我在这里错过了什么?

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

由于两个typeinfo具有不同的地址,因此所描述的结构表示不同的类型。因此,强制转换应该已经失败,并且不应该捕获异常。

安腾ABI明确声明通过损坏的名称来比较类的type_info对象,这确实是您问题中假设的实现。

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

我想,这里的理由是完全支持你所观察到的行为。

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

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

在程序和我从程序中dlopen的共享库中定义了同一个类-祝贺您违反了一个定义规则。在这个行为不明确的国度里,任何事情都有可能发生,你应该知道。

相关文章: