Ste*_*rst 20 c++ gcc visual-studio c-preprocessor
我正在尝试构建一个调试日志消息函数,该函数记录调用日志消息的位置的文件,行和函数.
#define DEBUG_PANIC(p) CLogging::Debuglogf( "Debug marker (%s) - ::%s() in file: %s(%d)", p, __func__ , __FILE__, __LINE__ );
Run Code Online (Sandbox Code Playgroud)
上面的代码适用于某些编译器,但不是全部.我的代码需要与GCC以及Microsoft Visual工作室交叉兼容.我已添加以下定义以帮助兼容性.
#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__ );
Run Code Online (Sandbox Code Playgroud)
上面代码片段的问题在于#else宏在所有编译器上都处于活动状态,而其他宏则没有.换句话说#if defined __func__,在编译器上是假的,其中__func__是预定义的宏.
我的问题是
__func__可以使用?Luc*_*ore 24
你假设__func__是一个宏,但事实并非如此.它是条件支持的预定义标识符,因此您无法使用#if defined或检查它#ifdef.
如果编译器无法告诉你这是否支持(他们可以通过一个_FUNC_SUPPORTED或者什么,我不是说他们实际上是这样做的),你将不得不检查编译器而不是实际的标识符.
一些事情:
#ifndef __FUNCTION_NAME__
#ifdef WIN32 //WINDOWS
#define __FUNCTION_NAME__ __FUNCTION__
#else //*NIX
#define __FUNCTION_NAME__ __func__
#endif
#endif
Run Code Online (Sandbox Code Playgroud)
小智 7
它们既不是预处理器宏
__FILE__ and __LINE__,也不是变量.
取自以下链接:
http://gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Function-Names.html
另外,请查看与您类似的其他问题:
如何检查是否可以使用__PRETTY_FUNCTION__?
例:
#ifdef _MSC_VER // Visual Studio
#define FUNCTION_NAME __FUNCTION__
#endif
Run Code Online (Sandbox Code Playgroud)
我想补充一点,__FUNCTION__宏是为GCC和MSVC定义的。尽管是非标准的,但在两个编译器上均可用。
GCC标准预定义宏引用:
C99引入了
__func__,而GCC提供__FUNCTION__了很长时间。这两个都是包含当前函数名称的字符串(语义稍有不同;请参见GCC手册)。它们都不是宏。预处理器不知道当前函数的名称。但是,它们往往与__FILE__和结合使用很有用__LINE__。
MSVC预定义宏引用:
__FUNCTION__仅在功能中有效。将封闭函数的未修饰名称定义为字符串文字。
__FUNCTION__如果使用/ EP或/ P编译器选项,则不会展开。参见
__FUNCDNAME__示例。
因此可以使用__FUNCTION__,因为两个编译器都可以实现。尽管您在两个编译器上可能不会获得相同的结果,但是在某些情况下可能是可以接受的。