函数名__func__的预定义宏

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)

  • 符合C99或更高版本*的任何C编译器必须*支持`__func__`; 从这个意义上讲,它不是一个可选功能.因此,支持`__func__`的一种方法是检查`__STDC_VERSION__> = 199901L`.(虽然前C99或不合格的编译器可以支持它作为扩展.) (13认同)
  • 啊,好点; OP没有为该语言添加标签.直到2011年,C++标准才强制要求`__func__`.它可能是前C++ 11编译器的常见扩展. (5认同)
  • @KeithThompson我假设使用C ++。但主要要点是它不是宏。 (3认同)

Jea*_*avy 12

通常BoostBOOST_CURRENT_FUNCTION定义的跨平台解决方案<boost/current_function.hpp>.


小智 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)


non*_*kle 5

我想补充一点,__FUNCTION__宏是为GCC和MSVC定义的。尽管是非标准的,但在两个编译器上均可用。

GCC标准预定义宏引用:

C99引入了__func__,而GCC提供__FUNCTION__了很长时间。这两个都是包含当前函数名称的字符串(语义稍有不同;请参见GCC手册)。它们都不是宏。预处理器不知道当前函数的名称。但是,它们往往与__FILE__和结合使用很有用__LINE__

MSVC预定义宏引用:

__FUNCTION__

仅在功能中有效。将封闭函数的未修饰名称定义为字符串文字。

__FUNCTION__ 如果使用/ EP或/ P编译器选项,则不会展开。

参见__FUNCDNAME__示例。

因此可以使用__FUNCTION__,因为两个编译器都可以实现。尽管您在两个编译器上可能不会获得相同的结果,但是在某些情况下可能是可以接受的。

  • _我想补充一点,`__FUNCTION__` 宏是为 GCC 和 MSVC 定义的。_ 文档引用明确指出这**不是**宏。 (2认同)