2013-01-02 9 views
7

Widzę dziwną awarię, gdy dynamic_cast powraca NULL na kompilatorze clang. Ale ten sam kod działa ze środowiskiem gcc.dynamic_cast na kompilatorze llvm clang nie działa

Czy możesz wskazać mi, co może być przyczyną? Jaka może być różnica między dynamic_cast dla llvm i gcc.

Używam domyślnego zachowania zarówno kompilatora, gdzie domyślnie RTTI jest włączone.

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; 
} 

Jeszcze jedna obserwacja: Z gcc

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

działa doskonale, jak oczekiwano, ale z brzękiem

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

porównanie pokazuje różne zachowania .. nie jestem pewien dokładnie, dlaczego tak różni.

Dzięki

+7

To może być wiele rzeczy. Czy jesteś pewien, że typ jest taki sam w obu kompilatorach? I ma tabelę metod wirtualnych w obu kompilatorach? Czy w obu kompilatorach jest włączone RTTI? Spróbuj zmniejszyć problem do małego przykładu i opublikuj go razem z komendami kompilatora. –

+0

Nie pisz tego w komentarzach, EDYTUJ PYTANIE! Dodatkowe informacje powinny zawsze zostać dodane do treści pytania. Dlatego są edytowalne! –

+0

Spróbuj wydrukować komunikaty debugowania: 'typeid (** it)' oraz 'typeid (T)' -i 'typeid (* it)' oraz 'typeid (T *)'. Przenieś również wyrażenie 'dynamic_cast' poza warunek i sprawdź, czy zwracana jest wartość' NULL' - odlewanie dynamiczne wykonuje porównanie typu, ale akceptuje również instancje potomne. –

Odpowiedz

0

dla kodu jak ten, dobrym pomysłem jest statycznie czy klasa T pochodzi od MsgList. Używając boost, można to zrobić w następujący sposób:

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

Powiązane problemy