今天我的一位同事来问我标题中提到的问题 他目前正在尝试减少代码库的二进制文件占用空间,这也用于小型目标(如Cortex M3等)。显然他们决定在RTTI打开的情况下进行编译(实际上是GCC),以支持正确的异常处理。
嗯,他的主要抱怨是为什么std::type_info::name()
实际上需要RTTI的支持,并问,如果我知道一种方法来抑制生成支持这个所需的字符串文字,或者至少是缩短他们。
的std :: TYPE_INFO ::名称
const char* name() const;
返回包含类型名称的实现定义的以null结尾的字符串。没有给出任何保证,特别是返回的字符串对于几种类型可以是相同的,并且在相同程序的调用之间进行更改。
A, - 但是编译器特定的 - ,例如, 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's answer很好地解决了,我已经接受了它。对于代码中使用的任何异常,剩下的生成std::type_info
实例的剩余子问题仍然存在。我们很漂亮当然,这些文字从未在任何地方使用过。
相关内容: Strip unused runtime functions which bloat executable (GCC)
答案 0 :(得分:16)
隔离这一位:
answer是肯定的:
-fno-rtti
禁止使用虚拟函数生成有关每个类的信息,以供C ++运行时类型标识功能(
dynamic_cast
和typeid
)使用。如果您不使用该语言的这些部分,则可以使用此标志来节省一些空间。 请注意,异常处理使用相同的信息,但会根据需要生成 。dynamic_cast
运算符仍可用于不需要运行时类型信息的转换,即转换为void *
或明确的基类。
答案 1 :(得分:6)
除了记录之外,
std::type_info::name()
是否存在现实生活,生产代码级用例?
Itanium ABI describes operator==
std::type_info
std::type_info::name()
如何在测试从type_info
返回的用于指针相等的字符串方面轻松实现。
在非平面地址空间中,可能有多个RTLD_LOCAL
对象用于相同类型(例如,因为动态库已加载operator==
){{{ 1}}可能需要使用strcmp
来确定两种类型是否相同。
因此name()
函数用于确定两个type_info
对象是否引用相同的类型。有关实际用例的示例,通常用于标准库中的至少两个位置,std::function<F>::target<T>()
和std::get_deleter<D>(const std::shared_ptr<T>&)
。
如果您不使用RTTI,那么所有这些都无关紧要,因为您无论如何都不会拥有任何type_info
个对象(因此在libstdc ++中function::target
和{ {1}}无法使用功能。
我认为GCC的异常处理代码使用get_deleter
个对象本身的地址,而不是type_info
返回的字符串的地址,所以如果你使用异常但没有RTTI { <1}}不需要字符串。