简体   繁体   English

C ++中的RTTI和可移植性

[英]RTTI and Portability in C++

If a compiler doesn't "support" RTTI, does that mean that the compiler can not handle class hierarchies that have virtual functions in them? 如果编译器不“支持”RTTI,那是否意味着编译器无法处理其中包含虚函数的类层次结构? Or have I been misunderstanding the literature about how RTTI isn't portable, and the issues lie elsewhere? 或者我是否误解了关于RTTI如何不便携的文献,问题出在其他地方?

Thank you all for your comments! 谢谢大家的意见!

This is probably way more of an answer you were looking for, but here goes: 这可能是你正在寻找的更多答案,但这里有:

RTTI is not "portable" means that if you use compiler A to build dynamic library A, and use compiler B to build application B that links with A, then you cannot use RTTI, because the RTTI implementations of compiler a and b are different. RTTI不是“可移植的”意味着如果使用编译器A来构建动态库A,并使用编译器B来构建与A链接的应用程序B,那么就不能使用RTTI,因为编译器a和b的RTTI实现是不同的。 Virtual function are affected only because the virtual function mechanism may not be binary compatible either. 虚函数仅受影响,因为虚函数机制也可能不是二进制兼容的。

This issue was very important in the mid 90's, but the issue is now obsolete. 这个问题在90年代中期非常重要,但问题现在已经过时了。 Not because compliers have now all become binary compatible with each other, but rather the opposite: C++ developers have now recognized that C++ libraries must be delivered as source code, and not linkable libraries. 并不是因为编译器现在都变得彼此二进制兼容,而是相反:C ++开发人员现在已经认识到C ++库必须作为源代码提供,而不是可链接的库。 For those who view C++ as an extension of C, this is very discomforting, but for more modern programmers, who grew up in an open source enviroment, nothing special at all. 对于那些将C ++视为C语言扩展的人来说,这是非常令人不安的,但对于那些在开源环境中长大的现代程序员来说,没什么特别的。

What changed between the mid-90's and now is differing attitudes between what constitutes valuable intellectual property and what doesn't. 在90年代中期和现在之间发生了什么变化,是什么构成了有价值的知识产权与什么不是知识产权之间存在着不同的态度。 To wit: there is actually a patent registered with USPO on "expression templates." 也就是说:实际上在USPO上注册了一个关于“表达模板”的专利。 Even the holder of such realizes that the patent is unenforcable. 甚至这样的持有者也意识到该专利是不可行的。

C style "header and binary" libraries were long seen as a way to obfuscate valuable source code. C风格的“标题和二进制”库长期以来被视为混淆有价值的源代码的一种方式。 More and more, business came to recognize that the obfuscation was more self-defeating than protective: there is very little code out there that meets "valuable IP" status. 越来越多的企业开始认识到,混淆更多的是自我挫败而不是保护:那里的代码很少,符合“有价值的知识产权”的地位。 Most people buy libraries not because of the special IP it contains, but because it is cheaper to buy rather than roll their own. 大多数人购买图书馆不是因为它包含特殊的IP,而是因为它更便宜而不是自己购买。 In fact: expertise in applying IP is far more valuable than the IP itself. 事实上:应用知识产权的专业知识远比知识产权本身更有价值。 But if no one cares about this IP because theyh don't know about it, then it is not worth very much. 但如果没有人关心这个IP,因为他们不知道它,那么它就不值得了。

This is how open source works: IP is freely distrbuted, in return those distributors gain consultancy fees in applying that IP. 这就是开源的工作方式:IP是自由分配的,作为回报,这些分销商在申请该IP时获得咨询费。 Those who can figure it out for themselves profitably -- well good on them. 那些能够为自己找到利润的人 - 对他们有好处。 But it is not the norm. 但这不是常态。 What happpens actually is that a developer understands IP and sells their employer on buying the product that implements it. 实际上令人高兴的是,开发人员了解知识产权并在购买实施该产品的产品时出售其雇主。 Yeah, whole "developer communities" are founded on this premise. 是的,整个“开发者社区”都建立在这个前提下。

To make a long story short: binary (and subsequently RTTI) compatibilty went the way of the dinosaur once the open source movement took off, and concurrently, C++ template libraries became the norm. 长话短说:一旦开源运动起飞,二进制(以及随后的RTTI)兼容就像恐龙一样,同时,C ++模板库成为常态。 C++ libraries long ago became "source distributable only" like Perl, Python, JavaScript etc. To make your C++ compiler work with all source that you compile with it, make sure that RTTI is turned on (inideed all C++ standard features, like exceptions), and that all C++ libs you link are likewise commpied with the same options that you used to compile your app. C ++库很久以前就变成了“仅源可分发”,比如Perl,Python,JavaScript等。为了让你的C ++编译器能够使用你用它编译的所有源代码,确保打开RTTI(包括所有C ++标准功能,例如异常) ,并且您链接的所有C ++库同样使用与编译应用程序相同的选项。

There is one (and only one) compiler I know of that does not enable RTTI by default, and that is beccause there are other legacy ways to do the same thing. 我知道有一个(也是唯一一个)编译器默认情况下不启用RTTI,这是因为还有其他传统方法可以做同样的事情。 To read about these, pick up a copy of Don Box's excellent work "Essential COM." 要了解这些,请选择Don Box的优秀作品“Essential COM”。

RTTI is not needed for virtual functions. 虚拟功能不需要RTTI。

It is mainly used for dynamic_cast and typeid . 它主要用于dynamic_casttypeid

The only part of RTTI that is unportable is the format of strings returned from type_info::name() . RTTI中唯一不可移植的部分是从type_info::name()返回的字符串格式。

Even this has a fighting chance so long as you can find a c++filt tool for your compiler that converts (unmangles) such a string back into a compliant C++ type. 即使这样也有争斗的机会,只要你能为你的编译器找到一个c++filt工具,它可以将这样的字符串转换为(unmangles)一个兼容的C ++类型。

If a compiler doesn't "support" RTTI, does that mean that the compiler can not handle class hierarchies that have virtual functions in them? 如果编译器不“支持”RTTI,那是否意味着编译器无法处理其中包含虚函数的类层次结构?

Generally all modern C++ compilers support RTTI... So forget about it. 通常所有现代C ++编译器都支持RTTI ......所以不要忘了它。

Or have I been misunderstanding the literature about how RTTI isn't portable, and the issues lie elsewhere? 或者我是否误解了关于RTTI如何不便携的文献,问题出在其他地方?

RTTI today is portable and works fine on any modern compiler... However some special cases may occur. RTTI今天是便携式的,适用于任何现代编译器......但是可能会出现一些特殊情况。

Under ELF platforms (Linux) when you load libraries dynamically (ie dlopen) and try to perform dynamic_cast to some class between library and executable it may fail if you do not pass correct flags for linking executable (-rdynamic). 在ELF平台(Linux)下,当您动态加载库(即dlopen)并尝试对库和可执行文件之间的某个类执行dynamic_cast时,如果您没有传递正确的标志来链接可执行文件(-rdynamic),则可能会失败。

Almost any other cases... Just works. 几乎任何其他情况......只是工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM