C++ std::type_info::name()的实际用途是什么?
今天我的一位同事来问我标题中提到的问题。C++ std::type_info::name()的实际用途是什么?,c++,c++11,gcc,C++,C++11,Gcc,今天我的一位同事来问我标题中提到的问题。 他目前正试图减少代码库的二进制文件占用,这种代码库也用于小目标(如Cortex M3等)。显然,他们已经决定在RTTI打开的情况下编译(实际上是GCC),以支持正确的异常处理 好的,他的主要抱怨是,为什么实际上需要支持RTTI,并询问,我是否知道一种方法来抑制生成支持RTTI所需的字符串文本,或者至少缩短它们 std::type_info::name const char*name()const 返回包含类型名称的实现定义的以null结尾的字符串。没有给
他目前正试图减少代码库的二进制文件占用,这种代码库也用于小目标(如Cortex M3等)。显然,他们已经决定在RTTI打开的情况下编译(实际上是GCC),以支持正确的异常处理 好的,他的主要抱怨是,为什么实际上需要支持RTTI,并询问,我是否知道一种方法来抑制生成支持RTTI所需的字符串文本,或者至少缩短它们 std::type_info::name
const char*name()const代码>
返回包含类型名称的实现定义的以null结尾的字符串。没有给出任何保证,特别是,返回的字符串对于几种类型可能是相同的,并且在同一程序的调用之间会发生变化
例如dynamic\u cast
运算符的一个具体编译器实现不会使用此信息,而是类似于用于类型确定的哈希标记(类似于带有异常处理的catch()
块)。
我认为后者在目前的标准定义中得到了明确的表述
我不得不同意,除了用于调试(记录)目的之外,我也不认为使用std::type_info::name()
有什么意义。我不能百分之百肯定,在当前版本的GCC中,如果没有RTTI(我认为他们使用的是4.9.1),异常处理就可以正常工作,因此我犹豫是否建议干脆关闭RTTI。
另外,在他们的代码库中使用了dynamic\u cast
,但对于这些,我只是建议不要使用它,而是使用static\u cast
(他们实际上没有插件之类的东西,也不需要断言以外的运行时类型检测)
问题:
- 对于
std::type\u info::name()
,除了日志记录之外,是否存在真实的生产代码级用例
次级问题(更具体):
- 有人知道如何克服(解决)这些无用字符串文本的生成(假设它们永远不会被使用)吗
- RTTI真的(仍然)需要支持GCC的异常处理吗?
(这一部分现在已经很好地解决了,我已经接受了。对于代码中使用的任何异常,剩下的生成的std::type_info
实例的另一个子问题仍然存在。我们非常确定,这些文本从未在任何地方使用过)
相关位:隔离此位:
- 问题是,如果他们关闭RTTI,异常处理在GCC中还能正常工作吗李>
答案是肯定的:
-fno rtti
禁用具有虚拟函数的每类信息的生成,供C++运行时类型识别功能使用(<代码>动态Case< <代码> >代码> Type ID>代码>。如果不使用语言的这些部分,可以使用此标志节省一些空间请注意,异常处理使用相同的信息,但它会根据需要生成该信息。
dynamic_cast
运算符仍然可以用于不需要运行时类型信息的转换,即转换为void*
或明确的基类
对于std::type\u info::name()
,除了日志记录之外,是否存在真实的生产代码级用例
对于std::type_info
对象,安腾ABI how操作符==
可以通过测试从std::type_info::name()
返回的字符串来实现指针相等
在非平面地址空间中,同一类型可能有多个type\u info
对象(例如,因为动态库已加载RTLD\u LOCAL
),实现操作符==
可能需要使用strcmp
来确定两种类型是否相同
因此,name()
函数用于确定两个type\u info
对象是否引用相同的类型。对于实际用例的示例,通常至少在标准库中的两个位置使用,即std::function::target()
和std::get_deleter(const std::shared_ptr&)
如果您没有使用RTTI,那么所有这些都无关紧要,因为您无论如何都不会有任何type\u info
对象(因此在libstdc++中,function::target
和get\u deleter
函数不能使用)
我认为GCC的异常处理代码使用type\u info
对象本身的地址,而不是name()
返回的字符串地址,因此如果使用异常但不使用RTTI,则不需要name()
字符串。对于日志记录也不是很有用,因为名称可能是一个破损的名称,实际上没有太多直接的说明。我怀疑在生产中是否应该使用任何明确标记为“实现定义”而没有最基本的平等保证的东西,即使它是100%安全的。@JoachimPileborg甚至参考文档都提到了c++filt
:使用gcc和clang等编译器,返回的字符串可以通过c++filt-t管道传输,以转换为人类可读的形式。“@JoachimPileborg因为它在某些实现中可能没有用处,所以您不会在任何实现中使用它?关于子问题#1:对于小型嵌入式目标,这通常是链接器脚本可以帮助您解决的问题域。本质上,如果文本被放在二进制文件中的某个特定部分(我不确定gcc将它们放在哪里),您可以排除该部分。否则,可以显式排除与模式匹配的符号名称;您可能能够设计一种方案来抑制结果二进制文件中的文字(这显然是错误的)