c++ - dynamic_cast con RTTI desactivado
dynamic-cast (3)
Tengo curiosidad por saber qué sucede al compilar código con un reparto dinámico con RTTI desactivado (ya sea con -fno-rtti
en GCC o con /GR-
en Visual Studio). ¿El compilador "retrocede" a static_cast
? Dado que (al menos en VS) solo emite una advertencia, ¿qué hará el código compilado?
Más específicamente, qué cosas malas podrían pasar si compilo sin RTTI un código donde estoy seguro de que no hay ningún error posible con dynamic_cast (es decir, donde dynamic_cast
podría ser reemplazado de forma segura por un static_cast
) como este:
class A{ /*...*/ } ;
class B : public A {
int foo() { return 42 ;}
} ;
//...
A * myA = new B() ;
int bar = (dynamic_cast<B*>(myA))->foo() ;
En MSVC, si su código no está compilado con RTTI habilitado, se __non_rtti_object
una excepción __non_rtti_object
, si la __non_rtti_object
no se puede realizar sin una verificación en tiempo de ejecución.
La forma más fácil de averiguarlo es probarlo.
Lo que encontrará es que algunos de sus lanzamientos dinámicos se marcarán como ilegales. Algunos no lo harán. Por ejemplo, la conversión se conoce en el momento de la compilación cuando se utiliza la conversión dinámica para convertir a una clase base no ambigua.
Apéndice
Re " Dado que (al menos en VS) solo emite una advertencia ..." Ignore las advertencias a su propio riesgo. Lo mejor que puede hacer es asegurarse de que su código se compile sin advertencias, con niveles de advertencia establecidos muy altos (y posiblemente convertidos en errores). El segundo mejor es mirar cada una de las advertencias que recibe y asegurarse de que no suceda nada malo. En este caso, algo malo sucederá. Realmente no debería importarle cómo se implementa ese evento adverso. Lo que debe preocuparte es deshacerse de él.
Leyendo el estándar, en 5.2.7 / 6 encontramos que a menos que el objetivo sea una base no ambigua de la fuente, la fuente debe ser de tipo polimórfico. Luego en 10.3 / 1
Las funciones virtuales soportan el enlace dinámico y la programación orientada a objetos. Una clase que declara o hereda una función virtual se denomina clase polimórfica.
En otras palabras, el estándar no parece decir nada sobre su pregunta. En este caso, el estándar no permite que un compilador desactive RTTI, por lo que para cada compilador debe revisar su documentación para ver qué sucedería. Basado en esta lectura, creo que esta es una pregunta del compilador, no una pregunta en lenguaje C ++ como lo indica la etiqueta.
Alternativamente, puede evitar el problema completamente usando solo static_cast
cuando sepa que es suficiente.