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? 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.