dynamic_cast на llvm clang компилаторът е неуспешен

Виждам странен отказ, при който dynamic_cast връща NULL на компилатора на clang. Но същият код работи с gcc среда.

Бихте ли ми посочили каква може да е основната причина? Каква може да е разликата между dynamic_cast на llvm и gcc.

Използвам поведението по подразбиране и на двата компилатора, където мисля, че 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))

сравнението показва различно поведение.. не съм сигурен точно защо това се различава.

Благодаря


person Abhrajyoti Kirtania    schedule 02.01.2013    source източник
comment
Това може да са много неща. Сигурни ли сте, че типът е един и същ и в двата компилатора? И има ли таблица с виртуални методи в двата компилатора? И активиран ли е RTTI и в двата компилатора? Опитайте се да намалите проблема до малък пример и да го публикувате заедно с използваните команди на компилатора.   -  person Jan Hudec    schedule 02.01.2013
comment
Не го пишете в коментари, РЕДАКТИРАЙТЕ ВЪПРОСА! Винаги трябва да се добавят допълнителни подробности към тялото на въпроса. Ето защо те могат да се редактират!   -  person Jan Hudec    schedule 02.01.2013
comment
Опитайте да отпечатате typeid(**it) и typeid(T)—и typeid(*it) и typeid(T*)—в съобщенията за отстраняване на грешки. Също така преместете dynamic_cast извън условието и го проверете за връщане на NULL—динамичното предаване прави вътрешно сравнение на typeid, но приема и наследствени екземпляри.   -  person Jan Hudec    schedule 03.01.2013
comment
Бях отпечатал и typeid(*(*it)).name() и typeid(T).name(), и двете са еднакви и дори направих проверка, след като преместих dynamic_cast извън условието. Показвам ясно, че dynamic_cast връща само NULL. Не съм сигурен точно защо! Още една точка за ваша информация, MsgList ще съдържа msg, който ще бъде изграден с GSoap по време на изпълнение. Не разбирам как може да се различава, тъй като виждам, че същият код работи перфектно с gcc.   -  person Abhrajyoti Kirtania    schedule 03.01.2013
comment
Какви версии на всеки компилатор използвате? На коя платформа и версия на платформа сте? Когато казвате, че сравнението показва различно поведение, какво е това различно поведение?   -  person bames53    schedule 03.01.2013
comment
Xcode 4.5. Платформа: Mac OSX Mountain Lion; Време за изпълнение със среда на clang if (typeid(*(*it)) == typeid(T)) инструкция винаги показва невярна стойност, но ако отпечатам това като typeid(*(*it)).name () и typeid(T).name(); показва същото име на клас.   -  person Abhrajyoti Kirtania    schedule 05.01.2013
comment
Току-що се сблъсках със същия проблем. Имам rtti активиран.   -  person dcow    schedule 25.02.2016


Отговори (1)


За код като този, добра идея е статично да се гарантира, че класът T е извлечен от MsgList. Използвайки boost, това може да се направи по следния начин:

BOOST_STATIC_ASSERT((увеличение::е_база_и_извлечена::стойност));

person emilk    schedule 11.01.2013