C++ 函数名 __func__ 的预定义宏

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15305310/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 19:14:42  来源:igfitidea点击:

Predefined Macros for function name __func__

c++visual-studiogccc-preprocessor

提问by Steven smethurst

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.

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

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

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

My question is

我的问题是

  • How do I create a cross compiler macro to find the function name ?
  • How can I tell if a __func__can be used?
  • 如何创建交叉编译器宏来查找函数名称?
  • 如何判断 a 是否__func__可以使用?

回答by Luchian Grigore

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 definedor #ifdef.

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

If the compilers have no way of telling you whether this is supported (they could via a _FUNC_SUPPORTEDor something, I'm not saying they actually are doing this), you'll have to check the compiler instead of the actual identifier.

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

Something along the lines:

沿线的东西:

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

回答by Jean Davy

As often Boostis THE cross platform solution with BOOST_CURRENT_FUNCTIONdefined in <boost/current_function.hpp>.

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

回答by nonsensickle

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.

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

GCC Standard Predefined Macrosquote:

GCC 标准预定义宏引用:

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.

C99引入了__func__,GCC__FUNCTION__早就提供了。这两个都是包含当前函数名称的字符串(有轻微的语义差异;请参阅 GCC 手册)。它们都不是宏;预处理器不知道当前函数的名称。不过,它们往往与__FILE__和结合使用__LINE__

MSVC Predefined Macrosquote:

MSVC 预定义宏引用:

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

__FUNCTION__

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

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

参见__FUNCDNAME__示例。

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.

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

回答by alexfontaine

they are neither preprocessor macros, like __FILE__ and __LINE__, nor variables.

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

Taken from the following link:

取自以下链接:

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

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?

如何检查 __PRETTY_FUNCTION__ 是否可以使用?

Example:

例子:

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