2013-01-02 98 views
7

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

请问我可能是什么根源?在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)) 

比较表现出不同的行为..不知道到底为什么这是不同的。

由于

+7

这可能是很多事情。你确定这两种编译器的类型是一样的吗?并且在两个编译器中都有虚拟方法表?这两种编译器都支持RTTI吗?尝试将问题简化为一个小例子,并将其与使用的编译器命令一起发布。 –

+0

不要在评论中写下它,编辑问题!应该总是将其他细节添加到问题主体中。这就是为什么它们是可编辑的! –

+0

尝试在调试消息中打印'typeid(** it)'和'typeid(T)' - 和'typeid(* it)'和'typeid(T *)'。还要将'dynamic_cast'移出条件并检查它是否返回'NULL' - 动态转换在内部执行typeid比较,但它也接受后代实例。 –

回答

0

对于这样的代码,一个好主意是静态地确保类T从MsgList的。使用boost,可以这样做:

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