std::type_info::name()的实际用途是什么
What is the actual purpose of std::type_info::name()?
今天我的一位同事来问我标题中提到的问题
他目前正试图减少代码库的二进制足迹,该代码库也用于小型目标(如Cortex M3等)。显然,他们已经决定在打开RTTI的情况下进行编译(实际上是GCC),以支持正确的异常处理。
好吧,他的主要抱怨是为什么实际上需要std::type_info::name()
来支持RTTI,并问道,我是否知道一种方法来抑制支持这一点所需的字符串文字的生成,或者至少缩短它们。
std::type_info::name
const char* name() const;
返回一个实现定义的以null结尾的字符串,该字符串包含类型的名称。没有给出任何保证,特别是,对于几种类型,返回的字符串可能是相同的,并且在同一程序的调用之间会发生变化。
例如,dynamic_cast<>
运算符的实现(尽管是编译器特定的)不会使用此信息,而是类似于用于类型确定的散列标记(类似于具有异常处理的catch()
块)
我认为的现行标准定义清楚地表达了后者
std::type_info::hash_code
std::type_index
我不得不同意,除了用于调试(日志记录)之外,我也不认为使用std::type_info::name()
有什么意义。我不能100%确定在没有RTTI的情况下,异常处理是否能在当前版本的GCC中工作(我认为他们使用的是4.9.1),所以我犹豫是否建议简单地关闭RTTI
此外,在他们的代码库中使用了dynamic_casts<>
,但对于这些,我只是建议不要使用它,而使用static_cast
(它们实际上没有插件之类的东西,也不需要断言之外的运行时类型检测)。
问题:
- 除了日志记录之外,
std::type_info::name()
是否还存在现实生活中的生产代码级别用例
子问题(更具体):
-
有人知道如何克服(解决)这些无用字符串文字的生成(假设它们永远不会被使用)吗?
-
RTTI真的(仍然)需要支持GCC的异常处理吗
(@Sehe的回答很好地解决了这一部分,我已经接受了。对于代码中使用的任何异常,剩下的生成的std::type_info
实例仍然存在另一个子问题。我们非常确信,这些文字从未在任何地方使用过)
相关位:剥离膨胀可执行文件(GCC)的未使用的运行时函数
隔离此位:
- 关键是,如果他们关闭RTTI,异常处理在GCC中还能正常工作吗?——πάγταῥεῖ1小时前
答案是肯定的:
-fno-rtti
禁用生成关于每个具有虚拟函数的类的信息,以供C++运行时类型标识功能(
dynamic_cast
和typeid
)使用。如果你不使用语言的这些部分,你可以通过使用这个标志来节省一些空间请注意,异常处理使用相同的信息,但它会根据需要生成信息。dynamic_cast
运算符仍然可以用于不需要运行时类型信息的强制转换,即强制转换为void *
或明确的基类。
除了日志记录之外,
std::type_info::name()
是否还存在现实生活中的生产代码级别用例?
安腾ABI描述了std::type_info
对象的operator==
是如何通过测试从std::type_info::name()
返回的字符串来实现指针相等的。
在非平面地址空间中,可能具有相同类型的多个type_info
对象(例如,因为动态库已加载了RTLD_LOCAL
),operator==
的实现可能需要使用strcmp
来确定两个类型是否相同。
因此,name()
函数用于确定两个type_info
对象是否引用相同的类型。对于真实用例的示例,它通常至少在标准库中的两个位置使用,即std::function<F>::target<T>()
和std::get_deleter<D>(const std::shared_ptr<T>&)
。
如果您不使用RTTI,那么所有这些都无关紧要,因为您无论如何都不会有任何type_info
对象(因此在libstdc++中不能使用function::target
和get_deleter
函数)。
我认为GCC的异常处理代码使用type_info
对象本身的地址,而不是name()
返回的字符串的地址,所以如果您使用异常但没有RTTI,则不需要name()
字符串。
- "type* = nullptr"的含义是什么
- 警告的原因是什么:"when type is in parentheses, array cannot have dynamic size"?
- C++ - "Incomplete type not allowed"错误是什么意思,我该如何修复它?
- 这是什么意思:"member reference type 'Human *' is a pointer; did you mean to use '->'?"
- C++ 中数组的"expression must have pointer-to-object type"是什么?
- "conversion from void to non scalar type string"是什么意思?
- 在 LLVM 中,调用中函数的位播"type"是什么?如何访问此功能?
- C++中的"vector<type[n]>"是什么?
- "type-safety"在C++中的确切含义是什么?
- 在OpenCV中,std::vector而不是cv::Mat的"type"是什么解释,我该如何更改它?(C++)
- c++ 声明中的 ::type 是什么意思
- "Cannot overload functions distinguished by return type alone"是什么意思?
- cmake -D <var>:<type>=<value> 参数"-D"是什么意思
- C++:声明'TYPE& name(&TYPE);'是什么意思?
- 这个错误是什么意思" expression must have pointer-to-class type"?
- 错误是什么意思"expression must have class type"?
- 'must have an argument of class or enumerated type'到底是什么意思
- "Expected '(' for function-style cast or type construction"错误是什么意思?
- &Type::变量是什么意思?
- 这个论点的声明是什么意思:"type (*name1) (const type& name2)"?