函数名__func__的预定义宏

时间:2013-03-08 23:50:14

标签: c++ visual-studio gcc c-preprocessor

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

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

上面的代码适用于某些编译器,但不是全部。我的代码需要与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__ );

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

我的问题是

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

4 个答案:

答案 0 :(得分:22)

你假设__func__是一个宏,但事实并非如此。这是有条件支持的预定义标识符,因此您无法使用#if defined#ifdef进行检查。

如果编译器无法告诉你这是否支持(它们可以通过_FUNC_SUPPORTED或其他东西,我不是说它们实际上是这样做的),你将不得不检查编译器而不是实际的标识符。

有些事情:

#ifndef __FUNCTION_NAME__
    #ifdef WIN32   //WINDOWS
        #define __FUNCTION_NAME__   __FUNCTION__  
    #else          //*NIX
        #define __FUNCTION_NAME__   __func__ 
    #endif
#endif

答案 1 :(得分:10)

通常Boost是在<boost/current_function.hpp>中定义BOOST_CURRENT_FUNCTION的跨平台解决方案。

答案 2 :(得分:6)

  

它们既不是预处理器宏,也不是__FILE__ and __LINE__,   也不是变数。

取自以下链接:

http://gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Function-Names.html

另外,请查看与您类似的其他问题:

How to check if __PRETTY_FUNCTION__ can be used?

示例:

#ifdef _MSC_VER // Visual Studio
    #define FUNCTION_NAME __FUNCTION__
#endif

答案 3 :(得分:4)

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

GCC Standard Predefined Macros引用:

  

C99介绍__func__,GCC长期提供__FUNCTION__。这两个都是包含当前函数名称的字符串(存在轻微的语义差异;请参阅GCC手册)。它们都不是宏观;预处理器不知道当前函数的名称。不过,它们往往与__FILE____LINE__结合使用。

MSVC Predefined Macros引用:

  

__FUNCTION__

     

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

     如果使用/ EP或/ P编译器选项,

__FUNCTION__不会展开。

     

请参阅__FUNCDNAME__以获取示例。

所以使用__FUNCTION__就行了,因为两个编译器都实现了它。虽然您可能无法在两个编译器上获得相同的结果,但在某些情况下这可能是可以接受的。