简体   繁体   中英

Predefined Macros for function name __func__

I am attempting to build a debug log message function that records the file, line, and function of of where the log message was called from.

#define DEBUG_PANIC(p) CLogging::Debuglogf( "Debug marker (%s) - ::%s() in file: %s(%d)", p, __func__ , __FILE__, __LINE__ );

The above code works on some compilers but not all. My code needs to be cross compatible with GCC as well as Microsoft Visual studios. I have added the below defines to help with compatibility.

#ifndef __FUNCTION_NAME__
    #if defined __func__ 
        // Undeclared 
        #define __FUNCTION_NAME__   __func__ 
    #elif defined __FUNCTION__ 
        // Undeclared
        #define __FUNCTION_NAME__   __FUNCTION__  
    #elif defined __PRETTY_FUNCTION__
        // Undeclared
        #define __FUNCTION_NAME__   __PRETTY_FUNCTION__
    #else
        // Declared
        #define __FUNCTION_NAME__   "N/A"   
    #endif // __func__ 

#endif // __FUNCTION_NAME__

#define DEBUG_PANIC(p) CLogging::Debuglogf( "Debug marker (%s) - ::%s() in file: %s(%d)", p, __FUNCTION_NAME__, __FILE__, __LINE__ );

The problem with the above code snippet is that it is the #else macro is active on all compilers while the other macros are not. in other words #if defined __func__ is false on compilers where __func__ is a predefined macro .

My question is

  • How do I create a cross compiler macro to find the function name ?
  • How can I tell if a __func__ can be used?

You're assuming __func__ is a macro, but it's not. It's a conditionally-supported predefined identifier, so you can't check it with #if defined or #ifdef .

If the compilers have no way of telling you whether this is supported (they could via a _FUNC_SUPPORTED or something, I'm not saying they actually are doing this), you'll have to check the compiler instead of the actual identifier.

Something along the lines:

#ifndef __FUNCTION_NAME__
    #ifdef WIN32   //WINDOWS
        #define __FUNCTION_NAME__   __FUNCTION__  
    #else          //*NIX
        #define __FUNCTION_NAME__   __func__ 
    #endif
#endif

通常Boost是具有在<boost/current_function.hpp>定义的BOOST_CURRENT_FUNCTION跨平台解决方案。

they are neither preprocessor macros, like __FILE__ and __LINE__ , nor variables.

Taken from the following link:

http://gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Function-Names.html

Also, please check out this other question that was answered that is similar to yours:

How to check if __PRETTY_FUNCTION__ can be used?

Example:

#ifdef _MSC_VER // Visual Studio
    #define FUNCTION_NAME __FUNCTION__
#endif

I would like to add that the __FUNCTION__ macro is defined for both GCC and MSVC. Though non-standard, it is available on both compilers.

GCC Standard Predefined Macros quote:

C99 introduces __func__ , and GCC has provided __FUNCTION__ for a long time. Both of these are strings containing the name of the current function (there are slight semantic differences; see the GCC manual). Neither of them is a macro; the preprocessor does not know the name of the current function. They tend to be useful in conjunction with __FILE__ and __LINE__ , though.

MSVC Predefined Macros quote:

__FUNCTION__

Valid only in a function. Defines the undecorated name of the enclosing function as a string literal.

__FUNCTION__ is not expanded if you use the /EP or /P compiler option.

See __FUNCDNAME__ for an example.

So using __FUNCTION__ would be ok, since both compilers implement it. Though you may not get the same results on both compilers but that might be acceptable in some situations.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM