【发布时间】:2015-03-04 18:10:24
【问题描述】:
今天我的一位同事来问我标题中提到的问题。
他目前正在尝试减少代码库的二进制占用空间,该代码库也用于小型目标(如 Cortex M3 等)。显然他们已经决定在打开 RTTI 的情况下进行编译(实际上是 GCC),以支持正确的异常处理。
好吧,他的主要抱怨是为什么实际上需要std::type_info::name() 来支持 RTTI,并问我是否知道一种方法来抑制生成支持这一点所需的字符串文字,或者至少缩短它们.
std::type_info::name
const char* name() const;返回包含类型名称的实现定义的以空字符结尾的字符串。不提供任何保证,特别是返回的字符串对于多种类型可以是相同的,并且在同一程序的调用之间会发生变化。
A ,- 但是编译器特定的-,例如的实现dynamic_cast<> 运算符不会使用此信息,而是使用类似于哈希标签的东西来确定类型(类似于 catch() 具有异常处理的块)。
我认为后者在当前的标准定义中明确表达了
我不得不同意,除了用于调试(记录)目的之外,我也没有真正看到使用 std::type_info::name() 的意义。我不是 100% 确定异常处理在没有 RTTI 的情况下使用当前版本的 GCC(我认为他们使用的是 4.9.1),所以我犹豫是否建议直接关闭 RTTI。
在他们的代码库中使用dynamic_casts<> 也是这种情况,但对于这些,我只是建议不要使用它,而支持static_cast (他们实际上没有插件之类的东西,或者不需要运行时类型检测除了断言)。
问题:
- 除了日志记录之外,
std::type_info::name()是否存在真实的生产代码级用例?
子问题(更具体):
有谁知道如何克服(解决)这些无用字符串文字的生成(假设它们永远不会被使用)?
真的(仍然)需要 RTTI 来支持 GCC 的异常处理吗?
(这部分现在由@Sehe's answer 很好地解决了,我已经接受了。对于代码中使用的任何异常,剩下的生成的std::type_info实例仍然存在另一个子问题。我们很确定,这些文字永远不会在任何地方使用)
相关位:Strip unused runtime functions which bloat executable (GCC)
【问题讨论】:
-
对于日志记录也不是很有用,因为名称可能是一个不能直接说明的名称。
-
我怀疑任何明确标记为“实现定义”而没有最基本的平等保证的东西都应该在生产中使用,即使它是 100% 安全的。
-
@JoachimPileborg 甚至参考文档也提到了
c++filt:“使用gcc和clang等编译器,返回的字符串可以通过c++filt -t管道转换为human-可读的形式。” -
@JoachimPileborg 因为它在一些实现上可能没用,你不会在any实现上使用它?
-
关于子问题 #1:对于小型嵌入式目标,这通常是链接描述文件可以帮助您的问题域。本质上,如果文字被放置在二进制文件的特定部分中(我不确定 gcc 将它们放在哪里),您可以排除该部分。否则,您可以明确排除与模式匹配的符号名称;您也许可以设计一种方案来抑制生成的二进制文件中的文字(如果曾经使用过它们,显然会在运行时失败)。