2013-01-02 19 views
7

Vedo uno strano errore in cui il dynamic_cast restituisce NULL nel compilatore clang. Ma lo stesso codice funziona con l'ambiente gcc.dynamic_cast sul compilatore clang llvm in errore

Potrebbe per favore indicarmi quale potrebbe essere la causa principale? Quale potrebbe essere la differenza tra dynamic_cast su llvm e gcc.

Sto utilizzando il comportamento predefinito di entrambi i compilatori in cui penso che RTTI sia abilitato per impostazione predefinita.

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

Un'altra osservazione: con GCC

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

è perfettamente funzionante come previsto, ma con clangore

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

confronto sta mostrando un comportamento diverso .. non so esattamente il motivo per cui questo differisce.

Grazie

+7

Questo potrebbe essere molte cose. Sei sicuro che il tipo sia lo stesso in entrambi i compilatori? E ha una tabella dei metodi virtuale in entrambi i compilatori? Ed è abilitato per RTTI in entrambi i compilatori? Prova a ridurre il problema su un piccolo esempio e pubblicalo insieme ai comandi del compilatore usati. –

+0

Non scrivere nei commenti, MODIFICA LA DOMANDA! Ulteriori dettagli dovrebbero essere sempre aggiunti al corpo della domanda. Ecco perché sono modificabili! –

+0

Prova a stampare il 'typeid (** it)' e 'typeid (T)' -and 'typeid (* it)' e 'typeid (T *)' -in messaggi di debug. Sposta anche il 'dynamic_cast' della condizione e controllalo per restituire' NULL'-il cast dinamico esegue internamente il confronto di tipo, ma accetta anche istanze discendenti. –

risposta

0

Per il codice come questo, una buona idea è di garantire in modo statico che la classe T è derivata da MsgList. Utilizzando boost, questo può essere fatto in questo modo:

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

Problemi correlati