views:

1267

answers:

4
class foo
{
public:
  void say_type_name()
  {
    std::cout << typeid(this).name() << std::endl;
  }
};

int main()
{
  foo f;;
  f.say_type_name();
}

Above code prints P3foo on my ubuntu machine with g++. I am not getting why it is printing P3foo instead of just foo. If I change the code like

    std::cout << typeid(*this).name() << std::endl;

it prints 3foo.

Any thoughts?

+12  A: 

Because it is a pointer to foo. And foo has 3 characters. So it becomes P3foo. The other one has type foo, so it becomes 3foo. Note that the text is implementation dependent, and in this case GCC just gives you the internal, mangled name.

Enter that mangled name into the program c++filt to get the unmangled name:

$ c++filt -t P3foo
foo*
Johannes Schaub - litb
WOW! Interesting. Two more questions.. 1 - c++filt is part of gcc distribution or part of LINUX? 2 - Is there any way to get the mangled name of a method or class?
Appu
c++filt is part of binutils (the package where ld (the linker) and the other small utils like readelf also come from): http://www.gnu.org/software/binutils/
Johannes Schaub - litb
there is no way to do that in C++. In GCC, however there is a function exposed by the ABI that does do this. It's in cxxabi.h and called __cxa_demangle . just pass it the mangled name. Its interface follows this ABI: http://www.codesourcery.com/public/cxx-abi/abi.html#demangler
Johannes Schaub - litb
Many thanks litb.
Appu
Also remember that the result of typeid().name() is going to be implementation dependent. I do not believe that there is even a requirement that it yield something intelligible much less human readable.
D.Shawley
visual c++, i believe, even yields a human readable string. but indeed there is no requirement for that. many things regarding type_info are unspecified (It's described in 18.5.1 in the C++ standard).
Johannes Schaub - litb
A: 

Is there a portable solution to demangle it runtime (e.g. demangle(typeid(anything).name())?)

Imre
+4  A: 

std::type_info::name() returns an implementation specific name. AFAIK, there is no portable way to get a "nice" name, although GCC has one. Look at abi::__cxa_demangle().

int status;
char *realname = abi::__cxa_demangle(typeid(obj).name(), 0, 0, &status);
std::cout << realname;
free(realname);
Ilia K.
Thanks for this! It was a great help in my current project.
Joe
A: 

Is there a portable solution

workaround would be to make a template hack to return all harcoded type names as char*

which platform dont have #include ?

-- http://rzr.online.fr/q/cxx

rzr
Without special support from the class itself (like `whoami()` method) any "template hack" can only output a *static* type, not the *dynamic* one (consider a pointer to polymorphic base class).
Ilia K.