3

如果编译器不“支持”RTTI,这是否意味着编译器无法处理其中包含虚函数的类层次结构?还是我误解了有关 RTTI 不便携的文献,而问题出在其他地方?

谢谢大家的意见!

4

4 回答 4

13

这可能是您正在寻找的更多答案,但这里是:

RTTI 不是“可移植的”意味着如果你使用编译器 A 构建动态库 A,并使用编译器 B 构建与 A 链接的应用程序 B,那么你不能使用 RTTI,因为编译器 a 和 b 的 RTTI 实现不同。虚函数受到影响只是因为虚函数机制也可能不是二进制兼容的。

这个问题在 90 年代中期非常重要,但现在已经过时了。不是因为编译器现在都变得相互兼容,而是相反:C++ 开发人员现在已经认识到 C++ 库必须作为源代码而不是可链接库来交付。对于那些将 C++ 视为 C 的扩展的人来说,这是非常令人不安的,但对于在开源环境中长大的更现代的程序员来说,这并没有什么特别之处。

从 90 年代中期到现在发生的变化是,对什么构成有价值的知识产权和什么不构成不同的态度。也就是说:实际上在美国专利局注册了一项关于“表达模板”的专利。甚至此类专利的持有者也意识到该专利是不可执行的。

C 风格的“头文件和二进制”库长期以来被视为一种混淆有价值的源代码的方法。越来越多的企业开始认识到,这种混淆更多的是弄巧成拙而不是保护:很少有代码符合“有价值的 IP”的地位。大多数人购买图书馆不是因为它包含的特殊 IP,而是因为购买比自己推出更便宜。事实上:应用知识产权的专业知识远比知识产权本身更有价值。但是如果没有人关心这个IP,因为他们不知道它,那么它就不值得了。

这就是开源的运作方式:IP 是免费分发的,作为回报,这些分销商在应用该 IP 时获得咨询费。那些能够为自己弄清楚并从中获利的人——对他们很好。但这不是常态。实际上发生的是开发人员了解 IP 并在购买实现它的产品时向他们的雇主出售。是的,整个“开发者社区”都是建立在这个前提之上的。

长话短说:一旦开源运动开始,二进制(以及随后的 RTTI)兼容性就像恐龙一样,同时,C++ 模板库成为常态。很久以前,C++ 库就像 Perl、Python、JavaScript 等一样成为“仅可分发的源代码”。为了使您的 C++ 编译器与您使用它编译的所有源代码一起工作,请确保打开 RTTI(包括所有 C++ 标准功能,如异常) ,并且您链接的所有 C++ 库也同样使用与编译应用程序相同的选项。

我知道有一个(也是唯一一个)编译器默认情况下不启用 RTTI,这是因为还有其他传统方法可以做同样的事情。要阅读这些内容,请阅读 Don Box 的优秀作品“Essential COM”。

于 2010-04-25T23:08:32.650 回答
9

虚拟功能不需要 RTTI。

主要用于dynamic_casttypeid

于 2010-04-25T19:50:51.507 回答
1

RTTI 唯一不可移植的部分是从type_info::name().

只要您可以c++filt为您的编译器找到一个工具,将这样的字符串转换(解开)回兼容的 C++ 类型,即使这样也有机会。

于 2010-04-25T19:49:31.833 回答
0

如果编译器不“支持”RTTI,这是否意味着编译器无法处理其中包含虚函数的类层次结构?

一般来说,所有现代 C++ 编译器都支持 RTTI ......所以算了吧。

还是我误解了有关 RTTI 不便携的文献,而问题出在其他地方?

今天的 RTTI 是可移植的,并且可以在任何现代编译器上正常工作......但是可能会发生一些特殊情况。

在 ELF 平台 (Linux) 下,当您动态加载库(即 dlopen)并尝试对库和可执行文件之间的某个类执行 dynamic_cast 时,如果您没有传递正确的标志来链接可执行文件(-rdynamic) ,它可能会失败。

几乎所有其他情况......只是工作。

于 2010-04-25T19:56:48.427 回答