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
Xкод 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((boost::is_base_and_derived::value));

person emilk    schedule 11.01.2013