Я вижу очень странный сбой, очень похожий на проблему, описанную в dynamic_cast при сбое компилятора llvm clang: dynamic_cast
возвращает nullptr
, когда я пытаюсь преобразовать базовый тип в производный тип для объекта производного типа. Хотя в моем случае typeid
на самом деле показывает тот же динамический тип.
Ниже приведена функция отладки, которую я использую для проверки типов во время выполнения. Он берет указатель SrcType*
и пытается динамически привести его к указателю DstType*
. Если преобразование завершается неудачно, т. е. возвращаемый указатель равен nullptr
, выводится сообщение об ошибке. Макрос VERIFY()
проверяет истинность условия:
template<typename DstType, typename SrcType>
void CheckDynamicType( SrcType *pSrcPtr )
{
VERIFY(dynamic_cast<DstType*> (pSrcPtr) != nullptr,
"Dynamic type cast failed. Src typeid: \'", typeid(*pSrcPtr).name(),
"\' Dst typeid: \'", typeid(DstType).name(), '\'');
}
И вот вывод, который я получаю:
Dynamic type cast failed. Src typeid: 'N8Diligent15RefCountersImplE' Dst typeid: 'N8Diligent15RefCountersImplE'
Я использую компилятор clang из набора инструментов Android ndk r16. Я компилирую с флагом rtti. Тот же код отлично работает на gcc и msvc. Еще немного информации: код также отлично работает, если я соберу его со средой выполнения gnustl
(я не уверен, как gnu stl работает с clang, но тем не менее).
ОБНОВИТЬ
Потратив еще несколько часов на изучение проблемы, я обнаружил, что dynamic_cast
дает сбой, когда он используется для объекта, созданного в другом модуле. Из этого Использование clang++, -fvisibility=hidden и typeinfo и type-erasure и эти сообщения похоже, что dynamic_cast
должно работать, если класс помечен __attribute__((visibility("default")))
, так что typeid
структуры из двух модулей будут объединены. Это, однако, тоже не помогает, и я все еще вижу проблему.
VERIFY()
макрос проверяет, истинно ли выражение, и в противном случае печатает отладочное сообщение (я обновил вопрос, чтобы прояснить это). @ Öö-Tiib, значит, это не опечатка. @RustyXDynamic type cast failed
печатается, если это действительно не удалось (т.е.dynamic_cast
вернулоnullptr
), но тогдаtypeid
показывает тот же тип, что и является моей проблемой - person Egor   schedule 16.11.2017false
. Таким образом, смысл сообщения, которое он печатает, заключается в том, чтоdynamic_cast
вернулnullptr
, ноtypeid
делает вывод, что динамические типы действительно совпадают, что для меня не имеет смысла. - person Egor   schedule 16.11.2017typeid
, напечатанный макросом, является правильным и ожидаемым идентификатором типа. Итак, получается, что у меня естьSrcType
иDstType
, для которыхtypeid(SrcType).name() == typeid(DstType).name()
, ноdynamic_cast<DstType*>(pSrcPtr) == nullptr
. Я использую самую последнюю версию ndk, но строю для armv7. - person Egor   schedule 16.11.2017dynamic_cast
для объекта, созданного в другом модуле. Это оказалось известной проблемой, и это сообщение russellmcc.com /posts/2013-08-03-rtti.html#foot1 предполагает, что маркировка класса с помощью__attribute__((visibility("default")))
должна помочь, но я все еще вижу проблему. - person Egor   schedule 17.11.2017typeid
в двух модулях, а затем сравнивает только указатели, которые отличаются. Это не связано со статической или динамической версией библиотеки времени выполнения. Пометка видимости класса по умолчанию тоже почему-то не помогает. - person Egor   schedule 17.11.2017