Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ std::type_info::name()的实际用途是什么?_C++_C++11_Gcc - Fatal编程技术网

C++ std::type_info::name()的实际用途是什么?

C++ std::type_info::name()的实际用途是什么?,c++,c++11,gcc,C++,C++11,Gcc,今天我的一位同事来问我标题中提到的问题。 他目前正试图减少代码库的二进制文件占用,这种代码库也用于小目标(如Cortex M3等)。显然,他们已经决定在RTTI打开的情况下编译(实际上是GCC),以支持正确的异常处理 好的,他的主要抱怨是,为什么实际上需要支持RTTI,并询问,我是否知道一种方法来抑制生成支持RTTI所需的字符串文本,或者至少缩短它们 std::type_info::name const char*name()const 返回包含类型名称的实现定义的以null结尾的字符串。没有给

今天我的一位同事来问我标题中提到的问题。
他目前正试图减少代码库的二进制文件占用,这种代码库也用于小目标(如Cortex M3等)。显然,他们已经决定在RTTI打开的情况下编译(实际上是GCC),以支持正确的异常处理

好的,他的主要抱怨是,为什么实际上需要支持RTTI,并询问,我是否知道一种方法来抑制生成支持RTTI所需的字符串文本,或者至少缩短它们

std::type_info::name
const char*name()const
返回包含类型名称的实现定义的以null结尾的字符串。没有给出任何保证,特别是,返回的字符串对于几种类型可能是相同的,并且在同一程序的调用之间会发生变化

例如
dynamic\u cast
运算符的一个具体编译器实现不会使用此信息,而是类似于用于类型确定的哈希标记(类似于带有异常处理的
catch()
块)。
我认为后者在目前的标准定义中得到了明确的表述

  • 我不得不同意,除了用于调试(记录)目的之外,我也不认为使用
    std::type_info::name()
    有什么意义。我不能百分之百肯定,在当前版本的GCC中,如果没有RTTI(我认为他们使用的是4.9.1),异常处理就可以正常工作,因此我犹豫是否建议干脆关闭RTTI。
    另外,在他们的代码库中使用了
    dynamic\u cast
    ,但对于这些,我只是建议不要使用它,而是使用
    static\u cast
    (他们实际上没有插件之类的东西,也不需要断言以外的运行时类型检测)


    问题:
    • 对于
      std::type\u info::name()
      ,除了日志记录之外,是否存在真实的生产代码级用例
    次级问题(更具体):
    • 有人知道如何克服(解决)这些无用字符串文本的生成(假设它们永远不会被使用)吗

    • RTTI真的(仍然)需要支持GCC的异常处理吗?
      (这一部分现在已经很好地解决了,我已经接受了。对于代码中使用的任何异常,剩下的生成的
      std::type_info
      实例的另一个子问题仍然存在。我们非常确定,这些文本从未在任何地方使用过)


    相关位:

    隔离此位:

    • 问题是,如果他们关闭RTTI,异常处理在GCC中还能正常工作吗
    答案是肯定的:

    -fno rtti

    禁用具有虚拟函数的每类信息的生成,供C++运行时类型识别功能使用(<代码>动态Case< <代码> >代码> Type ID>代码>。如果不使用语言的这些部分,可以使用此标志节省一些空间请注意,异常处理使用相同的信息,但它会根据需要生成该信息

    dynamic_cast
    运算符仍然可以用于不需要运行时类型信息的转换,即转换为
    void*
    或明确的基类

    对于
    std::type\u info::name()
    ,除了日志记录之外,是否存在真实的生产代码级用例

    对于
    std::type_info
    对象,安腾ABI how
    操作符==
    可以通过测试从
    std::type_info::name()
    返回的字符串来实现指针相等

    在非平面地址空间中,同一类型可能有多个
    type\u info
    对象(例如,因为动态库已加载
    RTLD\u LOCAL
    ),实现
    操作符==
    可能需要使用
    strcmp
    来确定两种类型是否相同

    因此,
    name()
    函数用于确定两个
    type\u info
    对象是否引用相同的类型。对于实际用例的示例,通常至少在标准库中的两个位置使用,即
    std::function::target()
    std::get_deleter(const std::shared_ptr&)

    如果您没有使用RTTI,那么所有这些都无关紧要,因为您无论如何都不会有任何
    type\u info
    对象(因此在libstdc++中,
    function::target
    get\u deleter
    函数不能使用)


    我认为GCC的异常处理代码使用
    type\u info
    对象本身的地址,而不是
    name()
    返回的字符串地址,因此如果使用异常但不使用RTTI,则不需要
    name()
    字符串。

    对于日志记录也不是很有用,因为名称可能是一个破损的名称,实际上没有太多直接的说明。我怀疑在生产中是否应该使用任何明确标记为“实现定义”而没有最基本的平等保证的东西,即使它是100%安全的。@JoachimPileborg甚至参考文档都提到了
    c++filt
    :使用gcc和clang等编译器,返回的字符串可以通过c++filt-t管道传输,以转换为人类可读的形式。“@JoachimPileborg因为它在某些实现中可能没有用处,所以您不会在任何实现中使用它?关于子问题#1:对于小型嵌入式目标,这通常是链接器脚本可以帮助您解决的问题域。本质上,如果文本被放在二进制文件中的某个特定部分(我不确定gcc将它们放在哪里),您可以排除该部分。否则,可以显式排除与模式匹配的符号名称;您可能能够设计一种方案来抑制结果二进制文件中的文字(这显然是错误的)