dynamic_cast在clang上跨模块边界不起作用

时间:2017-11-16 06:18:42

标签: android c++ android-ndk llvm-clang

我看到一个非常奇怪的失败,与我所描述的问题非常相似 dynamic_cast on llvm clang compiler failingdynamic_cast当我尝试从基类型向下转换为派生类型时,对于派生类型的对象,返回nullptr。在我的情况下,虽然typeid实际上显示了相同的动态类型。

下面是我用来验证运行时类型的调试函数。它需要一个SrcType*的指针,并尝试将其动态转换为DstType*的指针。如果转换失败,即返回的指针为nullptr,则会输出错误消息。 VERIFY()宏检查条件是否为真:

template<typename DstType, typename SrcType>
void CheckDynamicType( SrcType *pSrcPtr )
{
    VERIFY(dynamic_cast<DstType*> (pSrcPtr) != nullptr, 
           "Dynamic type cast failed. Src typeid: \'", typeid(*pSrcPtr).name(), 
           "\' Dst typeid: \'", typeid(DstType).name(), '\'');
}

这是我得到的输出:

Dynamic type cast failed. Src typeid: 'N8Diligent15RefCountersImplE' Dst typeid: 'N8Diligent15RefCountersImplE'

我正在使用Android ndk r16工具链中的clang编译器。我正在用rtti标志进行编译。相同的代码在gcc和msvc上工作正常。 另一点信息:如果我用gnustl运行时构建代码也可以正常工作(我不确定gnu stl如何与clang一起工作,但无论如何)。

更新

在花了几个小时研究这个问题后,我发现dynamic_cast在另一个模块中创建的对象上使用时失败了。 由此 dynamic_castUsing clang++, -fvisibility=hidden, and typeinfo, and type-erasure帖子如果该类标有__attribute__((visibility("default"))),则typeid应该有效,以便合并来自两个模块的#include <stdio.h> /* copy input to output */ main() { int c; c = getchar(); while(c != EOF) { putchar(c); c = getchar(); } return 0; } 个结构。然而,这也没有帮助,我仍然看到了这个问题。

1 个答案:

答案 0 :(得分:-2)

如果你正在使用股票系统编译器,那么编译器的dynamic_cast几乎不可能正常工作。这在系统软件的各个方面都得到了广泛的测试和使用。