禁用RTTI的dynamic_cast

Lou*_*uen 23 c++ dynamic-cast rtti

我很想知道在使用动态强制转换RTTI禁用时(无论是-fno-rtti在GCC上还是/GR-在Visual Studio上)编译代码时会发生什么.编译器"退回"了static_cast吗?由于(至少在VS上)它只发出警告,编译的代码会做什么?

更具体地说,如果我在没有RTTI的情况下编译代码,那么可能会发生什么不好的事情我确信dynamic_cast没有错误(即dynamic_cast可以安全地替换为a static_cast),如下所示:

class A{ /*...*/ } ;
class B : public A {
    int foo() { return 42 ;}
} ;
//...
A * myA = new B() ;
int bar = (dynamic_cast<B*>(myA))->foo() ;
Run Code Online (Sandbox Code Playgroud)

Mar*_*k B 11

阅读标准,在5.2.7/6中我们发现,除非目标是源的明确基础,否则源必须是多态类型.然后在10.3/1

虚函数支持动态绑定和面向对象的编程.声明或继承虚函数的类称为多态类.

换句话说,标准似乎没有说明你的问题.在这种情况下,标准不允许编译器关闭RTTI,因此对于每个编译器,您需要检查其文档以查看将发生的情况.根据这个读数,我认为这是一个编译器问题,而不是标签所指示的C++语言问题.

或者,只要static_cast您知道它就足够了,您就可以完全避免这个问题.


Joh*_*ing 8

在MSVC中,如果您的代码未在启用RTTI的__non_rtti_object情况下编译,则如果在没有运行时检查的情况下无法执行强制转换,则会引发异常.


Dav*_*men 6

最简单的方法是尝试一下.

你会发现你的一些动态演员阵容将被标记为非法.有些人不会.例如,当您使用动态强制转换为明确的基类时,转换在编译时是已知的.

附录
" 因为(至少在VS上)它只会发出警告 ......"忽略警告你的危险.最好的办法是确保您的代码在没有警告的情况下编译,警告级别设置得非常高(并且可能转换为错误).第二个最好的方法是查看你得到的每一个警告,并确保不会发生任何不幸事件.在这种情况下,会发生一些不幸的事情.你真的不应该关心这个不幸的事件是如何实现的.你应该关心的是摆脱它.