30

我正在尝试构建一个调试日志消息函数,该函数记录调用日志消息的文件、行和函数。

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

上面的代码适用于一些编译器,但不是全部。我的代码需要与 GCC 以及 Microsoft Visual Studio 交叉兼容。我添加了以下定义以帮助兼容性。

#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__ );

上述代码片段的问题在于 #else 宏在所有编译器上都处于活动状态,而其他宏则没有。换句话说,在预定义宏#if defined __func__的编译器上是错误__func__的。

我的问题是

  • 如何创建交叉编译器宏来查找函数名称?
  • 如何判断 a 是否__func__可以使用?
4

4 回答 4

35

你假设__func__是一个宏,但它不是。它是有条件支持的预定义标识符,因此您不能使用#if definedor对其进行检查#ifdef

如果编译器无法告诉您这是否受支持(他们可以通过 a_FUNC_SUPPORTED或其他方式,我并不是说他们实际上正在这样做),您将不得不检查编译器而不是实际标识符。

类似的东西:

#ifndef __FUNCTION_NAME__
    #ifdef WIN32   //WINDOWS
        #define __FUNCTION_NAME__   __FUNCTION__  
    #else          //*NIX
        #define __FUNCTION_NAME__   __func__ 
    #endif
#endif
于 2013-03-08T23:55:22.957 回答
16

Boost通常是BOOST_CURRENT_FUNCTION定义在<boost/current_function.hpp>.

于 2015-06-30T11:22:02.923 回答
10

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

GCC 标准预定义宏引用:

C99 引入__func__,GCC 提供__FUNCTION__了很长时间。这两个都是包含当前函数名称的字符串(存在细微的语义差异;请参阅 GCC 手册)。它们都不是宏;预处理器不知道当前函数的名称。不过,它们往往与__FILE__and结合使用__LINE__

MSVC 预定义宏引用:

__FUNCTION__

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

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

参见__FUNCDNAME__示例。

所以使用__FUNCTION__就可以了,因为两个编译器都实现了它。尽管您可能在两个编译器上得到的结果不同,但在某些情况下这可能是可以接受的。

于 2016-01-06T22:47:28.490 回答
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
于 2013-03-08T23:55:11.490 回答