今天我的一位同事来问我标题中提到的问题.
他目前正在尝试减少代码库的二进制文件占用空间,这也用于小型目标(如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)的未使用的运行时函数
是否可以为constexpr变量分配唯一的地址,即对于变量可用的所有翻译单元(通常通过标题)都是相同的?请考虑以下示例:
// foo.hh
#include <iostream>
constexpr int foo = 42;
// a.cc
#include "foo.hh"
void a(void) { std::cout << "a: " << &foo << std::endl; }
// b.cc
#include "foo.hh"
extern void a(void);
int main(int argc, char** argv) {
a();
std::cout << "b: " << &foo << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
使用gcc 4.7 编译a.cc和b.cc分开并将它们链接在一起,我看到打印了两个不同的地址.如果我extern在标题中添加关键字,我会收到链接器错误duplicate symbol _foo in: a.o and b.o,我觉得有点令人惊讶,因为我认为添加extern更有可能导致编译器从另一个对象导入该符号,而不是从当前对象导出它.但似乎我对这些事情的运作方式的理解是错误的.
是否有合理的方法在一个标题中声明constexpr,这样所有翻译单元都可以在其常量表达式中使用它,并且所有翻译单元都同意该符号的地址?我希望一些额外的代码来表示这个符号实际所属的单个翻译单元,就像没有的extern非extern变量一样constexpr.
它是否意味着保证相同的std::type_info::hash_code()值意味着相同的类型?
Cplusplus.com似乎声称:
此函数为任何两个比较相等的type_info对象返回相同的值,而不同的值则返回不同的值.[强调我的]
Cppreference似乎另有说法:
返回一个未指定的值,对于对象,它引用相同的类型.没有给出其他保证,特别是,值可以在同一程序的调用之间改变.[强调我的]
相关标准段落是:
§p18.7.1p7-8
size_t hash_code()const noexcept;
7返回:一个未指定的值,除了在程序的单次执行中,它应为任何两个比较相等的type_info对象返回相同的值.
8备注:实现应为两个不比较相等的type_info对象返回不同的值.[强调我的]
" 应该 "应该在上面的语境中是什么意思?如果段落8是一个要求,那么似乎不可能实现,除非运行时对程序中的所有符号名称进行某种全局统一以确保缺少哈希冲突,这似乎是标准的一个相当大的负担强加于实现,特别是对于一个被调用的函数hash_code().(Itanium实际上需要这个,但它显然是高于标准的额外要求.)
如果" 应该 "并不意味着具有约束力,那么这句话似乎是毫无意义的,也就是标准中的缺陷,因为要求实现尝试满足一个无法依赖的困难要求,不会产生任何价值,只会引起混淆和碎片化.任何人都知道为什么会这样吗?
编辑:也许"缺陷"太强了,但至少它是一个可能混淆的点,应该澄清,因为它显然误导了至少一个参考网站,并传递误导任何依赖它的人.此外,它实际上是可能实现的要求(只要受实现支持的类型的数量比范围更小size_t),如果全球uniquing是在运行时完成,如果标准是试图表明这为目前还不清楚理想的实施策略与否.