динамическая трансляция с отключенным RTTI - PullRequest
23 голосов
/ 07 октября 2011

Мне любопытно узнать, что происходит при компиляции кода с динамическим приведением без RTTI (либо с -fno-rtti в GCC, либо с /GR- в visual studio).Компилятор "возвращается" к 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() ;

Ответы [ 3 ]

11 голосов
/ 07 октября 2011

Читая стандарт, в 5.2.7 / 6 мы находим, что если цель не является однозначной основой источника, источник должен быть полиморфного типа. Тогда в 10,3 / 1

Виртуальные функции поддерживают динамическое связывание и исключают программирование. Класс, который объявляет или наследует виртуальную функцию называется полиморфным классом.

Другими словами, стандарт, похоже, ничего не говорит о вашем вопросе. В этом случае стандарт не позволяет компилятору отключать RTTI, поэтому для каждого компилятора вы должны проверить его документацию, чтобы увидеть, что произойдет. Исходя из этого прочтения, я думаю, что это вопрос компилятора, а не вопрос языка C ++, как указывает тег.

Кроме того, вы можете полностью избежать этой проблемы, просто используя static_cast, когда вы знаете, что этого достаточно.

8 голосов
/ 07 октября 2011

В MSVC, если ваш код не скомпилирован с включенным RTTI, будет выдано исключение __non_rtti_object, если приведение не может быть выполнено без проверки во время выполнения.

6 голосов
/ 07 октября 2011

Самый простой способ выяснить это - попробовать.

Вы обнаружите, что некоторые ваших динамических приведений будут помечены как недопустимые.Некоторые не будут.Например, преобразование известно во время компиляции, когда вы используете динамическое приведение для преобразования в однозначный базовый класс.

Приложение
Re " С (по крайней мере, для VS) он только выдает предупреждение ... "Игнорируйте предупреждения на свой страх и риск.Лучше всего сделать так, чтобы ваш код компилировался без предупреждений, а уровни предупреждений были установлены на очень высоком уровне (и, возможно, преобразованы в ошибки).Во-вторых, лучше всего посмотреть на каждое предупреждение, которое вы получаете, и убедиться, что ничего плохого не произойдет.В этом случае случится что-то неприятное.Вы действительно не должны заботиться о том, как реализовано это неблагоприятное событие.То, о чем вы должны заботиться, - это избавиться от него.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...