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, если трансляция не может быть выполнена без проверки времени выполнения.