Retrieve a Function’s Name Programmatically

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()"<

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__"<

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:

  • In Visual Studio 2005 it's on by default but it cannot be used with the /EP and /P compilation options. Notice that in this IDE the token __func__ isn't recognized. Use __FUNCTION__ instead.
  • Comeau users should use the token __FUNCTION__ instead of __func__.
  • C++ BuilderX uses a slightly different name for this identifier: __FUNC__.
  • GCC 3.0 and higher support __func__ and __FUNCTION__.

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<

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: [email protected]@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 }};
Share the Post:
Share on facebook
Share on twitter
Share on linkedin

Overview

Recent Articles:

©2023 Copyright DevX - All Rights Reserved. Registration or use of this site constitutes acceptance of our Terms of Service and Privacy Policy.

Sitemap