2013-01-02 35 views
7

dynamic_castがclangコンパイラでNULLを返しているところで奇妙なエラーが発生しています。しかし、同じコードがgcc環境で動作しています。llvm clangコンパイラでdynamic_castが失敗する

根本的な原因を教えてください。 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_STATIC_ASSERT((boost :: is_base_and_derived :: value));