2010-12-16 158 views
34

为什么当我运行这个main.cpp为什么typeid.name()使用GCC返回奇怪的字符,以及如何让它打印未加密的名字?

#include <iostream> 
#include <typeinfo> 

using namespace std; 

struct Blah {}; 

int main() { 
    cout << typeid(Blah).name() << endl; 
    return 0; 
} 

通过与GCC 4.4.4版本编译它:

g++ main.cpp 

我得到这个:

4Blah 

基于Visual C++ 2008,我会得到:

struct Blah 

有没有办法让它只是打印Blahstruct Blah

+0

[C++中打印变量类型]的可能重复(http://stackoverflow.com/questions/81870/print-variable-type-in​​-c) – 2015-06-18 15:13:03

+1

[Unmangling std :: type \ _info :: name](http://stackoverflow.com/questions/281818/unmangling-the-result-of-stdtype-in​​foname) – bain 2016-11-20 23:54:35

回答

52

name的返回值是实现定义的:实现甚至不需要为不同类型返回不同的字符串。

从g ++得到的是decorated name,您可以使用c++filt命令或__cxa_demangle“去镶嵌”。

+13

特别是'C++ filt -t' – 2015-01-16 13:09:58

+1

唉,该死的GCC – metamorphosis 2016-04-02 04:57:40

3

typeid().name()是依赖于实现的。它甚至可以为每种类型返回空字符串。这不是非常有用的实现,但它是有效的。

+0

不。它可能不会为每个类型返回空字符串。字符串表示的方式是应用程序定义的,但根据C++标准,它必须与其他类型不同。空弦你不能这样做。 – 2017-03-03 17:35:30

11

有没有办法让它只是打印

Blahstruct Blah

std::typeinfo::name()的结果未指定。它甚至可能为所有类型返回相同的字符串(实际上,对于所有类型而言,实际上是空字符串),并且实现仍然符合标准。你不能依靠它的结果。真的,我发现它唯一有用的是调试。

告诉我们你需要什么。性格常常是你用来代替的。

+0

在我的程序中,我只想将我的结构名称记录到日志文件中。按照上面的例子,我可以输入如下内容:'LOG(“Blah”);'。但是我想考虑将来可能会改变结构体的名称,所以我试着去做:'LOG(typeinfo(Blah).name();' – sivabudh 2010-12-16 22:24:26

+1

@ ShaChris23:好的,我想你会有并不是所有的编译器都以相同的方式进行编译,但是,看看运行时库发出的是什么,而不是'blah',你有一个字符串映射到字符串列表的向量,这很容易超过对于日志文件大小有任何明显的限制 – sbi 2010-12-17 08:35:46

16

返回的字符串是实现定义的。

gcc正在做的是返回损坏的名称。
您可以将重整名称转换为纯文本使用C++ filt的

> a.out | c++filt 
+0

下面是一个例子:假设stdout的内容是'PFPFiiEiiE',我们可以使用shell命令'echo' PFPFiiEiiE“| C++ filt',结果是'int(*(*)(int,int))(int)'。 – Hustlion 2017-09-02 11:05:46

6

正如其他人所说,这里的结果实现定义,这意味着执行(即,编译器工具链)是可以自由地定义它的想法,只要它在某个地方记录下来。

从C++标准,部分18.5.1/1 [lib.type.info]:

type_info描述键入由实现产生的信息。 这个类的对象有效地存储了一个指向该类型名称的指针,以及一个适合于比较两种类型的编码值,用于相等或整理顺序。类型的名称,编码规则和整理顺序全部未指定 ,程序之间可能会有所不同。

2

in 4Blah,4是你班上的字母数。例如,如果你的类名是myEmptyClass,那么它会打印12myEmptyClass。

相关问题