繁体   English   中英

dynamic_cast失败 - 取决于操作系统版本

[英]dynamic_cast fails - depending on OS Version

我有一个失败的动态演员。 类布局如下:

class A1
{
    public:
virtual int foo1()=0;
};

class A2
{
    public:
    virtual int foo2();
};

class A3
{
public:
   virtual int foo3();
};

class B : public A1, public A2, public A3 
{
   int bar();
};

现在我使用指针(因此不会发生切片)进行向下转换。

main()
{
   B b;

   A1* a1 = dynamic_cast<A1*> (&b); // ok
   B*  b1 = dynamic_cast<B*>  (a1); // ok

   A2* a2_1 = dynamic_cast<A2*> (a1); // OSX 10.7 ok, OSX 10.9 fail
   A2* a1_2 = dynamic_cast<A2*> (b1); // ok

};

向下倾斜的工作,向上的工作,但侧面工作总是不起作用。 在OSX 10.7下,侧面工作,在OSX 10.9下它没有(GCC 4.2使用动态c ++ stdlib)。 使用gdb查看vtable我可以清楚地看到列出的A2方法和成员。

我的问题:

a)侧播在技术上是否正确? 它应该工作还是运行时错误?
b)如果sidecast取决于运行时,这个运行时在哪里定义? 我一直认为这是二进制文件的一部分?
c)失败的dynamic_cast如何看待(当看装配时),以及如何追踪这些问题?

更新:这是我在系统控制台中看到的

11/01/15 14:16:27,435 APPNAMECHANGED [15280]:dynamic_cast错误1:以下两个type_info都应该具有公共可见性。 至少其中一个是隐藏的。 10A1,15A2。

所以c)得到了解答,至少对于OSX 10.9。 看看控制台。 (Linux,某人?)看起来像是一个关于符号可见性的问题。 Doc说(gcc.gnu.org/wiki/Visibility)

然而,这不是完整的故事 - 它变得更难。 默认情况下,符号可见性是“默认”,但如果链接器只遇到一个隐藏的定义 - 只有一个 - 那个typeinfo符号将永久隐藏(请记住C ++标准的ODR - 一个定义规则)。 对于所有符号都是如此,但更有可能对typeinfos产生影响; 没有vtable的类的typeinfo符号是在每个使用EH类的目标文件中按需定义的,并且是弱定义的,因此定义在链接时合并为一个副本。

这导致了下一个问题,

d)我们如何追踪哪个符号至少被标记为隐藏,以及在何处以及为何? 有没有工具来检查.o文件?

免责声明:我只会提出问题a)。

首先,根据[class.virtual] / 1, B显然是一个多态类型,因为它继承了一个虚函数(确切地说, B继承了三个不同的函数)。
现在考虑[expr.dynamic.cast] / 8:

如果CT指向或引用的类类型,则运行时检查在逻辑上执行如下:

  • 如果,在最派生对象指向的V(简称),以,V点(指)到的公共基类子对象C对象,并且如果只有一个类型的对象C从子对象衍生的尖(简称),以由v结果指向(引用)该C对象。
  • 否则, 如果v指向(引用)最派生对象的公共基类子对象,并且最派生对象的类型具有类型C的基类,即明确且公共的,则结果指向(引用)最派生对象的C子对象。
  • 否则,运行时检查失败

是的,它应该工作。

在我们发现可执行文件链接到dylib之后,问题终于得到了解决,dylib本身与c ++运行时静态链接,但是使用不同的编译器编译(gcc 4.8 vs clang)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM