c++filt 不会对 typeid 名称进行分解

Posted

技术标签:

【中文标题】c++filt 不会对 typeid 名称进行分解【英文标题】:c++filt does not demangle typeid name 【发布时间】: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 个字符)。 嗯,这很简单。谢谢,但只是想知道是否有更清洁的方法来获得相同的效果 【参考方案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 返回的缓冲区。

以上是关于c++filt 不会对 typeid 名称进行分解的主要内容,如果未能解决你的问题,请参考以下文章

C++-typeid-操作符

可以使用 c++filt 将解构后的名称写回 .s 文件本身吗?

c++filt命令分析awk的输出

我的 c++filt 似乎无法正常工作,没有输出更改

在C ++ 17中是否有针对typeid的逆函数?

是否有引用的typeid?