Dynamic_cast с отключенным RTTI
Мне любопытно узнать, что происходит при компиляции кода с динамическим преобразованием с отключенным RTTI
(либо с -fno-rtti
на GCC, либо с помощью /GR-
на визуальной студии). Подходит ли компилятор к static_cast
? Поскольку (по крайней мере, на VS) он выдает только предупреждение, что сделает скомпилированный код?
Более конкретно, какие плохие вещи могут произойти, если я скомпилирую без RTTI код, где я уверен, что с dynamic_cast нет ошибки (т.е. где dynamic_cast
можно было бы безопасно заменить на static_cast
), как этот
class A{ /*...*/ } ;
class B : public A {
int foo() { return 42 ;}
} ;
//...
A * myA = new B() ;
int bar = (dynamic_cast<B*>(myA))->foo() ;
Ответы
Ответ 1
Самый простой способ узнать - попробовать.
Что вы найдете, так это то, что некоторые ваши динамические роли будут помечены как незаконные. Некоторые не будут. Например, преобразование известно во время компиляции, когда вы используете динамическое преобразование в upcast для однозначного базового класса.
Добавление
Re "Поскольку (по крайней мере, на VS), он выдает только предупреждение..."
Игнорируйте предупреждения на свой страх и риск. Лучше всего сделать, чтобы ваш код компилировался без предупреждений, причем уровни предупреждений были установлены очень высокими (и, возможно, преобразованы в ошибки). Лучше всего посмотреть на каждое предупреждение, которое вы получаете, и гарантировать, что ничего не произойдет. В этом случае произойдет что-то несчастье. Вам действительно все равно, как это неблагоприятное событие будет реализовано. То, что вам нужно, это избавиться от него.
Ответ 2
Считывая стандарт, в 5.2.7/6 мы находим, что если цель не является однозначной базой источника, источником должен быть полиморфный тип. Тогда в 10.3/1
Виртуальные функции поддерживают динамическое связывание и объектно-ориентированные программирование. Класс, объявляющий или наследующий виртуальную функцию, называемый полиморфным классом.
Другими словами, стандарт, похоже, ничего не говорит о вашем вопросе. В этом случае стандарт не позволяет компилятору отключить RTTI, поэтому для каждого компилятора вам необходимо проверить его документацию, чтобы узнать, что произойдет. Основываясь на этом чтении, я думаю, что это вопрос компилятора, а не вопрос языка С++, как указывает тег.
В качестве альтернативы вы можете полностью избежать проблемы, просто используя static_cast
, когда вы это знаете.
Ответ 3
В MSVC, если ваш код не скомпилирован с включенным RTTI, будет выбрано исключение __non_rtti_object
, если трансляция не может быть выполнена без проверки времени выполнения.