【问题标题】:dynamic_cast on llvm clang compiler failingllvm clang编译器上的dynamic_cast失败
【发布时间】:2012-12-16 15:33:21
【问题描述】:

我看到一个奇怪的故障,dynamic_cast 在 clang 编译器上返回 NULL。但是相同的代码适用于 gcc 环境。

能否请您指出可能的根本原因是什么? llvm 和 gcc 上的dynamic_cast 之间可能有什么区别。

我正在使用我认为默认启用 RTTI 的两个编译器的默认行为。

template<typename T> T* 
find_msg_of_type(
    MsgList *list
) {
    T* msg = NULL;

    if (list) {
        for (std::vector<MsgList*>::iterator it = list->element.begin();
                                                        it != list->element.end();
                                                        it++) {// MsgList can be list of objects build with GSoap.
            if (typeid(*(*it)) == typeid(T)) {
                msg = dynamic_cast<T*>(*it); // Failing on clang but this same code is working with gcc compiler.
                break;
            }
        }
    }

    return msg;
}

另一个观察:使用 gcc

if (typeid(*(*it)) == typeid(T))

按预期完美运行,但使用叮当声

if (typeid(*(*it)) == typeid(T))

比较显示出不同的行为。不知道为什么会有所不同。

谢谢

【问题讨论】:

  • 这可能是很多事情。您确定两个编译器中的类型相同吗?并且在两个编译器中都有虚拟方法表吗?两个编译器都启用了 RTTI 吗?尝试将问题简化为一个小示例,并将其与使用的编译器命令一起发布。
  • 不要在 cmets 中写,编辑问题!应始终将其他详细信息添加到问题正文中。这就是为什么它们是可编辑的!
  • 尝试在调试消息中打印typeid(**it)typeid(T)——以及typeid(*it)typeid(T*)。还将dynamic_cast 移出条件并检查它是否返回NULL——动态转换在内部进行typeid 比较,但它也接受后代实例。
  • 我已经打印了 typeid(*(*it)).name() 和 typeid(T).name(),两者都是相同的,甚至在将 dynamic_cast 移出条件后我也进行了检查.我清楚地表明 dynamic_cast 只返回 NULL。不知道具体为什么!还有一点供您参考,MsgList 将保存 msg,它将在运行时使用 GSoap 构建。我不明白它有什么不同,因为我看到相同的代码可以完美地使用 gcc。
  • 您使用的每个编译器的版本是什么?你在哪个平台和平台版本上?当您说“比较表现出不同的行为”时,这种不同的行为是什么?

标签: c++ compilation llvm clang dynamic-cast


【解决方案1】:

对于这样的代码,一个好主意是静态确保类 T 派生自 MsgList。使用 boost,可以这样完成:

BOOST_STATIC_ASSERT((boost::is_base_and_derived::value));

【讨论】:

    猜你喜欢
    • 2019-06-22
    • 1970-01-01
    • 2011-02-02
    • 1970-01-01
    • 2014-03-11
    • 1970-01-01
    • 1970-01-01
    • 2013-04-29
    • 2020-01-19
    相关资源
    最近更新 更多