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
__func__
can be used? (C++11) The predefined identifier __func__ is implicitly defined as a string that contains the unqualified and unadorned name of the enclosing function.
Predefined macros are those that the compiler defines (in contrast to those user defines in the source file). Those macros must not be re-defined or undefined by user.
__FUNCTION__ is a pre-standard extension that some C compilers support (including gcc and Visual C++); in general, you should use __func__ where it is supported and only use __FUNCTION__ if you are using a compiler that does not support it (for example, Visual C++, which does not support C99 and does not yet support ...
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With