DevX HomePage

Retrieve a Function's Name Programmatically

Embedding a hard-coded string inside a function's body in order to retrieve that function's name can be tedious and bug-prone. Learn how to use a new C99 facility to obtain the function's name at runtime.
bject reflection libraries, debugging tools, and code analyzers often need to access functions' names at runtime. Until not long ago, the only portable way to accomplish this was to manually embed a hard-coded string with the function's name inside the function's body. Needless to say, this technique is very tedious and bug-prone. This article demonstrates how to use a new C99 facility to obtain a function's name at runtime.


How can you access the name of a currently executing function programmatically?


Use the __FUNCTION__ facility and its related macros.




Presenting the Problem
One of the frustrating phases of debugging an application consists of checking whether certain functions ever get called. A naïve solution to this problem consists of adding a cout expression—or printf() if you're using C—like this:


void myfunc()
{
cout<<"myfunc()"<<endl;
//..more code here
}
In a typical project that contains thousands of functions adding such an output statement to each function is a pain. Instead, you need a mechanism that will automate this process.

Retrieving a Function's Name
As a C++ programmer, you must have come across the built-in macros __TIME__ , __FILE__ and __DATE__ that are translated at compile time into strings containing the compilation time, the name of the translation unit being processed and the current date, respectively.

The latest ISO C standard, commonly known as C99, added to these intrinsic macros another useful macro-like expression called __func__ which reports the unadorned (i.e., non-mangled) name of the function from which it is accessed. Notice that __func__ isn't a macro because the preprocessor knows nothing about functions. Instead, it's implemented as an implicitly-declared const char array:


static const char __func__[] = "function-name";
Where "function name" is the actual name of the function. In order to activate this facility, some compilers require that you use certain compilation flags. Check the documentation of your compiler for specific details.

Using this facility, you can automate much of the drudgery associated with displaying a function's name manually, as this rewritten version of the previous example shows:


void myfunc()
{
cout<<"__FUNCTION__"<<endl;
}
It's worth noting that the official C99 standard defines the identifier __func__ for this purpose. However, ISO C++ doesn't fully-support all C99 extensions yet. Therefore, most vendors have settled for __FUNCTION__ instead. __FUNCTION__ is usually implemented as a macro defined as __func__. In this solution, I adhere to __FUNCTION__ because it's the most widely-supported name. You can find the exact token used by four leading compilers here: Once the mechanism for obtaining the current function's name is automated, you can define a function that displays the name of any function:

void show_name(const char * name)
{
cout<<name<<endl;
}
void myfunc()
{
show_name(__FUNCTION__); //output: myfunc
}
void foo()
{
show_name(__FUNCTION__); //output: foo
}
Recall that __FUNCTION__ is initialized immediately after the opening brace of a function. Therefore, foo() and myfunc() can safely use it in the argument list of show_name() without overriding it.




Signatures and Decorated Names
The __FUNCTION__ facility was deigned with C in mind. However, C++ programmers often need additional information about their functions. Visual Studio 2005 supports two more facilities as a non-standard extension: __FUNCDNAME__ and __FUNCSIG__ which translate into a function's decorated name and its signature, respectively. A function's decorated name can be useful when you want to check whether two compilers share the same ABI, for instance. Additionally, it can help you decipher cryptic linker errors. The intrepid among you may even use it to invoke a function with C++ linkage from a DLL! In the following example, show_name() reports the decorated name of a function:


void myfunc()
{
show_name(__FUNCDNAME__); //output: ?myfunc@@YAXXZ
}
A function's signature consists of the function's name, its parameter list, return type, and enclosing namespace(s). If it's a member function, its class name and const/volatile qualifiers are also part of the signature. The following code demonstrates the signature differences between two functions: a freestanding function and a const member function. Both functions have the same name, return type and parameter:

void myfunc()
{
show_name(__FUNCSIG__); // void __cdecl myfunc(void)
}
struct S
{
void myfunc() const
{
show_name(__FUNCSIG__);
//void __thiscall S::myfunc(void) const
}
};

Danny Kalev is a certified system analyst and software engineer specializing in C++ and the theoretical aspects of formal languages. He is the author of Informit C++ Reference Guide and The ANSI/ISO Professional C++ Programmer's Handbook. He was a member of the C++ standards committee between 1997 and 2000. Danny recently finished his MA in general linguistics summa cum laude. In his spare time he likes to listen to classical music, read Victorian literature, and explore natural languages such as Hittite, Basque, and Irish Gaelic. Additional interests include archeology and geology. He also gives lectures about programming languages and applied linguistics at academic institutes.


DevX is a division of Internet.com.
© Copyright 2010 Internet.com. All Rights Reserved. Legal Notices