I'm currently working on some logging code that supposed to - among other things - print information about the calling function. This should be relatively easy, standard C++ has a type_info class. This contains the name of the typeid'd class/function/etc. but it's mangled. It's not very usefull. I.e. typeid(std::vector).name() returns "St6vectorIiSaIiEE".
Is there a way to produce something usefull from this? Like 'std::vector' for the above example. If it only works for non-template classes, that's fine too.
The sollution should work for gcc, but it would be better if I could port it. It's for logging so it's not so important that it can't be turned of, but it should be helpfull for debugging.
-
It's implementation defined, so it's not something that's going to be portable. In MSVC++, name() is the undecorated name, and you have to look at raw_name() to get the decorated one.
Just a stab in the dark here, but under gcc, you might want to look at demangle.h -
I've always wanted to use type_info, but I'm sure that the result of the name() member function is non-standard and won't necessarily return anything that can be converted to a meaningful result.
If you are sticking to one compiler, there maybe a compiler specific function that will do what you want. Check the documentation. -
Take a look at
__cxa_demangle
which you can find atcxxabi.h
.terminus : I took, it's deprecated, according to the message I get. -
This is what we use. HAVE_CXA_DEMANGLE is only set if available (recent versions of GCC only).
#ifdef HAVE_CXA_DEMANGLE const char* demangle(const char* name) { char buf[1024]; unsigned int size=1024; int status; char* res = abi::__cxa_demangle (name, buf, &size, &status); return res; } #else const char* demangle(const char* name) { return name; } #endif
fuenfundachtzig : You need to include `#include`. -
Not a complete solution, but you may want to look at what some of the standard (or widely supported) macro's define. It's common in logging code to see the use of the macros:
__FUNCTION__ __FILE__ __LINE__ e.g.: log(__FILE__, __LINE__, __FUNCTION__, mymessage);
CesarB : Not to mention __PRETTY_FUNCTION__.KeithB : This will give you the information about where you are in the code. What the question was asking was a pretty name of a type, like std::vector.luke : He mentioned it was for debugging, and I stated it wasn't a complete solution. Other macros such as __FUNCDNAME__ will return the decorated name.Max Lybbert : Actually, re-reading the question, it was "I'm currently working on some logging code that supposed to - among other things - print information about the calling function." This works.terminus : It's not complete, since I don't know the namespace. This is allready in my code. But thanks anyway. -
Here, take a look at type_strings.cpp it contains a function that does what you want.
If you just look for a demangling tool, which you e.g. could use to mangle stuff shown in a log file, take a look at
c++filt
, which comes with binutils. It can demangle C++ and Java symbol names.KeithB : Just to note, both cxa_demange() (which the code linked to uses) and cx++filt are gcc specific. There is no portable way to do this.terminus : c++filt doesn't cut it, I need this stuff (or most of it) at compile-time, mostly done with macros. -
I also found a macro called _ _ PRETTY _ FUNCTION _ _, which does the trick. It gives a pretty function name (figures :)). This is what I needed.
I.e. it gives me the following:
virtual bool mutex::do_unlock()
But I don't think it works on other compilers.
Greg Rogers : Yes, __PRETTY_FUNCTION__ is gcc specific. -
Consider using an existing logging library, like log4cxx, instead of writing your own. It handles, among other things, outputting the location of each log line in your desired format. And much more.
-
// KeithB's solution is good, but has one serious flaw in that unless buf is static // it'll get trashed from the stack before it is returned in res - and will point who-knows-where // Here's that problem fixed, but the code is still non-re-entrant and not thread-safe. // Anyone care to improve it? #include <cxxabi.h> // todo: javadoc this properly const char* demangle(const char* name) { static char buf[1024]; size_t size = sizeof(buf); int status; // todo: char* res = abi::__cxa_demangle (name, buf, &size, &status); buf[sizeof(buf) - 1] = 0; // I'd hope __cxa_demangle does this when the name is huge, but just in case. return res; }
0 comments:
Post a Comment