今天我的一位同事来问我标题中提到的问题.
他目前正在尝试减少代码库的二进制文件占用空间,这也用于小型目标(如Cortex M3等).显然他们决定在RTTI打开的情况下进行编译(实际上是GCC),以支持正确的异常处理.
好吧,他的主要抱怨是为什么std::type_info::name()
实际上需要RTTI的支持,并问,如果我知道一种方法来抑制生成支持这一点所需的字符串文字,或者至少缩短它们.
的std :: TYPE_INFO ::名
const char* name() const;
返回包含类型名称的实现定义的以null结尾的字符串.不给出任何保证,特别是返回的字符串对于几种类型可以是相同的,并且在相同程序的调用之间改变.
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的答案,并且我已经接受了它.另外一个子问题仍然留给std::type_info
代码中使用的任何异常的剩余生成实例.我们很确定,这些文字永远不会随处使用)
相关的一点:删除膨胀可执行(GCC)的未使用的运行时函数
seh*_*ehe 16
隔离这个位:
的回答是肯定的:
-fno-rtti
禁止使用虚拟函数生成有关每个类的信息,以供C++运行时类型标识功能(
dynamic_cast
和typeid
)使用.如果您不使用该语言的那些部分,则可以使用此标志来节省一些空间.请注意,异常处理使用相同的信息,但会根据需要生成它.该dynamic_cast
运营商仍然可以使用,不需要运行时类型信息广播,即强制转换为void *
或以明确的基类.
是否有现实生活,生产代码级别的用例
std::type_info::name()
除了日志记录?
安腾ABI 介绍了如何operator==
为std::type_info
对象可以从返回的字符串测试的角度来容易实现std::type_info::name()
指针相等.
在非平坦的地址空间中,可能有多个type_info
对象用于相同类型(例如,因为已加载动态库RTLD_LOCAL
),operator==
可能需要使用实现strcmp
来确定两种类型是否相同.
因此该name()
函数用于确定两个type_info
对象是否引用相同的类型.有关实际用例的示例,通常用于标准库中的至少两个位置,in 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()
则不需要字符串.