Once And Only Onceing Printable Names Of Code Objects

Code (e.g. test frameworks) often wants to be able to report a printable name for an object in the code, a function, a variable, etc.

E.g. test frameworks, for a passing (or failing) test, or suite, or...

Often the "print name" and the internal C++ name for the test class or method or function are almost identical.

There are several ways of doing this:

The name can be entered twice

CppUnit::TestCaller<ComplexNumberTest> test( "testEquality",
&ComplexNumberTest::testEquality );

This is what CppUnit originally required.

RTTI

RunTimeTypeInformation, is convenient, e.g. as a way of avoiding redundant typing, by allowing the test framework to automatically print the class name. But it is extremely ill-defined in the C++ standard, and, in fact, a conforming implementation could return empty string for all class names.

Even when present, as in GnuCpp, it may be ugly. E.g. in GNU G++

class foo{};
cout << typeid(foo);
prints "3foo". If you want this to be nicely human readable, you need to remove the "3", or decode it to "class foo". Unfortunately, that sort of cleaning up of typeid is not portable across different C++ compilers.

Pre-processor macros

E.g.

CPPUNIT_TEST( testEquality );
expands to
CppUnit::TestCaller<ComplexNumberTest> test( "testEquality",
&ComplexNumberTest::testEquality );

Similarly, some people do

#define CLASS(classname)  class classname { public: string classname() { return ##classname; }

but this is quite ugly, a non-syntactic macro, widely deplored.

__FILE__

You can use the predefined macro name __FILE__. This is ANSI C standard, and so relatively portable. However, it is constraining because it requires you to put only one named object, e.g. only one named test case, per file.

__FUNCTION__

You can use the GNU GCC/G++ predefined strings __FUNCTION__, _func_ and __PRETTY_FUNCTION__ that return strings containing the function name, and possibly the full function name qualified by class, etc. The first two are in many compilers, but IIRC are not part of any C/C++ standard. The last is only in GCC, SFAIK.

Restricting yourself to __FUNCTION__ or _func_ is one reason to use free functions, as opposed to classes, as the basic testcase.

__PRETTY_FUNCTION__ can be parsed to extract class name. But this is highly non-portable.

Scripts

You can use scripts outside the language to do things like find all class declarations, and automatically write templates, functions, or methods that return printable strings.

E.g. grep for

class foo_c {
and output
template<class T> string classname() { return "unknown class"; }
template<foo_c> string classname() { return "foo_c"; }

I.e. implementing a more useful version of typeid yourself.

However, depending on scripts increases porting hassles. Do you use Perl, or Python, or Ruby, or tcl/tk? What version? Etc.


EditText of this page (last edited March 2, 2006) or FindPage with title or text search