【问题标题】:c++filt does not demangle typeid namec++filt 不会对 typeid 名称进行分解
【发布时间】:2013-09-25 13:04:06
【问题描述】:

我在 GCC C++ 编译器上运行代码,输出 type_info::name:

#include <iostream>
#include <typeinfo>

using namespace std;

class shape {
   protected:
   int color;
   public:
   virtual void draw() = 0;
   };


class Circle: public shape {
   protected:
   int color;
   public:
   Circle(int a = 0): color(a) {};
   void draw();
   };

   void Circle::draw() {
   cout<<"color: "<<color<<'\n';
   }

class triangle: public shape {
   protected:
   int color;
   public:
   triangle(int a = 0): color(a) {};
   void draw();
   };

   void triangle::draw() {
   cout<<"color: "<<color<<'\n';
   }

int main() {
   Circle* a;
   triangle* b;
   cout<<typeid(a).name()<<'\n';
   cout<<typeid(b).name()<<'\n';
   }

但我得到以下结果:

P6Circle
P8triangle

在拆解时,

./shape | c++filt  

我得到与之前相同的输出。还有其他解决方案吗?

【问题讨论】:

  • Name mangling for types 并没有那么复杂,在那种情况下肯定不会......我不知道你的问题的答案是什么,但一种解决方法是自己阅读类型。 P 指向6Circle 圆对象的指针(6 是名称的长度)...P 指向8triangle 三角形的指针(8 个字符)。
  • 嗯,这很简单。谢谢,但只是想知道是否有更清洁的方法来获得相同的效果

标签: c++ typeid typeinfo demangler c++filt


【解决方案1】:

您需要对类型使用c++filt -t,因此以下内容应该可以工作:

./shape | c++filt -t

man page for c++filt-t 表示以下内容:

尝试对类型和函数名称进行分解。默认情况下禁用此功能,因为重整类型通常仅在编译器内部使用,并且它们可能与非重整名称混淆。例如,一个名为“a”的函数被视为一个重整的类型名称,将被重整为“signed char”。

【讨论】:

    【解决方案2】:

    您使用的是哪个版本的 GCC(及其对应的libstdc++)?

    使用 GCC 4.8,我有

    static inline std::string 
     demangled_type_info_name(const std::type_info&ti)
    {
      int status = 0;
      return abi::__cxa_demangle(ti.name(),0,0,&status);
    }
    

    然后我可以使用

    std::cout << demangled_type_info_name(typeid(*ptr)) << std::endl;
    

    其中ptr 指向带有RTTI 的某个对象(即使用一些虚拟方法,尤其是虚拟析构函数)。

    【讨论】:

    • 那你应该升级到 GCC 4.8.1 因为typeid 在那里实现得更好。
    • 恭喜,您刚刚诱使数百人将内存泄漏添加到他们的应用程序中。您必须在创建返回字符串后释放abi::__cxa_dmangle 返回的缓冲区。
    猜你喜欢
    • 2023-03-19
    • 2021-12-04
    • 2015-04-01
    • 2012-05-23
    • 1970-01-01
    • 1970-01-01
    • 2020-12-28
    • 1970-01-01
    • 2014-03-23
    相关资源
    最近更新 更多