Just to get the function name, embed a hard-coded string in the function body. This method is tedious and easily leads to errors. Let's take a look at how to use the new C99 feature, obtain the function name when running the program.
The object reflection library, debugging tool, and Code Analyzer often need to access the function name at runtime. Not long ago, the only method that can complete this task and be portable, manually embed a hard-coded string with the name of the function in the function body. This method is monotonous and prone to errors. This article will demonstrate how to use the new C99 feature to obtain the function name at runtime.
So how can we obtain the function name from the currently running function programmatically?
The answer is: Use _ FUNCTION _ and related macros.
Issue
Generally, the most disturbing stage in debugging is to constantly check whether a specific function has been called. The solution to this problem is to add a cout or printf () -- if you use C language, as shown below:
Void myfunc () { Cout <"myfunc ()" <endl; // Other code } |
Generally, in a typical project, there are thousands of functions. To add such an output statement to each function, it is no doubt difficult to go to Shushan. Therefore, A mechanism is required to automatically complete this operation.
Get function name
As a C ++ programmer, you may often encounter macros such as _ TIME _, _ FILE _, and _ DATE _. during compilation, convert to the string containing the compilation time, the name of the conversion unit to be processed, and the current time respectively.
In the latest iso c standard, C99, as you know, adds another useful macro-like expression _ func __, it will report the unmodified (not cropped) and accessed function names. Note that __func _ is not a macro because the Preprocessor knows nothing about this function. Instead, it is implemented as an array of implicitly declared constant characters:
Static const char _ func _ [] = "function-name "; |
At function-name, it is the actual function name. To activate this feature, Some compilers need to use a specific compilation flag. Please refer to the relevant compiler documentation for specific information.
With it, we can avoid the trouble of manually modifying the function name. The above example can be rewritten as follows:
Void myfunc () { Cout <"_ FUNCTION _" <endl; } |
The _ func _ identifier defined by the official C99 standard for this purpose deserves your attention. However, iso c ++ does not fully support all C99 extensions. Therefore, most compiler providers use _ FUNCTION _ instead, while _ FUNCTION _ is usually a macro defined as _ func, it is because it has been widely supported by the majority.
In Visual Studio 2005, this feature is activated by default, but cannot be used together with/EP and/P compilation options. Note that _ func _ cannot be identified in the IDE environment, instead of _ FUNCTION.
Comeau users should also use _ FUNCTION _ instead of _ func __.
C ++ BuilderX users should use a slightly different name: __func __.
GCC 3.0 and later versions support both _ func _ and _ FUNCTION __.
Once the current function name can be automatically obtained, you can define a function that displays any function name as follows:
Void show_name (const char * name) { Cout <name <endl; }
Void myfunc () { Show_name (_ FUNCTION _); // output: myfunc }
Void foo () { Show_name (_ FUNCTION _); // output: foo } |
Because _ FUNCTION _ is initialized immediately after the braces of the FUNCTION, foo () and myfunc () functions can be safely used in the parameter list, do not worry about heavy load.
Signature and modifier name
The _ FUNCTION _ feature was originally designed for the C language. However, C ++ programmers often need additional information about their functions. In Visual Studio 2005, two other non-standard extended features are also supported: __funcdname _ and _ FUNCSIG _, which are translated into the modifier name and signature of a function respectively. Function modifiers are useful. For example, when you want to check whether two compilers share the same ABI, it can also help you crack Link errors with vague meanings, and even use it to call another function linked with C ++ from one DLL. In the following example, show_name () reports the function modifier:
Void myfunc () { Show_name (_ FUNCDNAME _); // output :? Myfunc @ YAXXZ } |
A function signature consists of the function name, parameter list, return type, and included namespace. If it is a member function, its class name and const/volatile qualifier will also be part of the signature. The following code demonstrates the differences between an independent function and a const member function signature. The names, return types, and parameters of the two functions are identical:
Void myfunc () { Show_name (_ FUNCSIG _); // void _ cdecl myfunc (void) }
Struct S { Void myfunc () const { Show_name (_ FUNCSIG _); // void _ thiscall S: myfunc (void) const } };
|