__PRETTY_FUNCTION__,__FUNCTION__,__func__有什么区别?
__PRETTY_FUNCTION__
, __FUNCTION__
__PRETTY_FUNCTION__
, __FUNCTION__
__func__
和它们在哪里logging有什么区别? 我如何决定使用哪一个?
__func__
是一个隐式声明的标识符,它在函数内部使用时,扩展为包含函数名称的字符数组variables。 它被添加到C99中。 从C99§6.4.2.2/ 1开始:
标识符
__func__
被翻译者隐式地声明,就好像紧跟着每个函数定义的__func__
括号一样,声明static const char __func__[] = "function-name";
出现,其中function名称是词汇封闭function的名称。 这个名字是这个函数的无名的名字。
请注意,它不是一个macros,它在预处理过程中没有特别的意义。
在C ++ 11中, __func__
被添加到C ++中,在C ++ 11中被指定为包含“一个实现定义的string”(C ++ 11§8.4.1[dcl.fct.def.general] / 8)与C中的说明一样有用(将__func__
添加到C ++的原始build议是N1642 )。
__FUNCTION__
是一些C编译器支持的标准扩展(包括gcc和Visual C ++); 一般来说,你应该在__func__
被支持的地方使用,只有在使用__FUNCTION__
如果你使用的编译器不支持它(例如,Visual C ++,它不支持C99,还不支持所有的C ++ 0x,不提供__func__
)。
__PRETTY_FUNCTION__
是一个gcc扩展,与__FUNCTION__
大致相同,只是对于C ++函数,它包含函数的“漂亮”名字,包括函数的签名。 Visual C ++有一个类似(但不完全相同)的扩展名__FUNCSIG__
。
对于非标准macros,您需要查阅编译器的文档。 Visual C ++扩展包含在C ++编译器的“预定义的macros”的MSDN文档中。 gcc文档扩展在gcc文档页面“Function Names as Strings”中进行了描述。
尽pipe这并不能完全回答原来的问题,但大部分谷歌用户都希望看到这个问题
对于GCC:
petanb@debian:~$ cat test.cpp #include <iostream> int main(int argc, char **argv) { std::cout << __func__ << std::endl << __FUNCTION__ << std::endl << __PRETTY_FUNCTION__ << std::endl; } petanb@debian:~$ g++ test.cpp petanb@debian:~$ petanb@debian:~$ ./a.out main main int main(int, char**)
__PRETTY_FUNCTION__
知道C ++的特性,比如类,名字空间和模板
#include <iostream> namespace N { class C { public: template <class T> static void f() { std::cout << __func__ << std::endl << __FUNCTION__ << std::endl << __PRETTY_FUNCTION__ << std::endl; } }; } int main() { N::C::f<int>(); }
输出GCC 4.8:
f f static void N::C::f() [with T = int]
__func__
在第8.4.1节的C ++ 0x标准中有logging。 在这种情况下,它是一个预定义的函数局部variables的forms:
static const char __func__[] = "function-name ";
其中“function名称”是实现特定的。 这意味着只要你声明一个函数,编译器就会将这个variables隐式地添加到你的函数中。 __FUNCTION__
和__PRETTY_FUNCTION__
也是如此。 尽pipe他们的大小,他们不是macros。 尽pipe__func__
是对C ++ 0x的补充
g++ -std=c++98 ....
仍然会使用__func__
编译代码。
__PRETTY_FUNCTION__
和__FUNCTION__
logging在这里http://gcc.gnu.org/onlinedocs/gcc-4.5.1/gcc/Function-Names.html#Function-Names 。 __FUNCTION__
只是__func__
另一个名字。 __PRETTY_FUNCTION__
与C中的__func__
相同,但在C ++中它也包含types签名。
对于那些谁想知道如何去VS.
MSVC 2015更新1,cl.exe版本19.00.24215.1:
#include <iostream> template<typename X, typename Y> struct A { template<typename Z> static void f() { std::cout << "from A::f():" << std::endl << __FUNCTION__ << std::endl << __func__ << std::endl << __FUNCSIG__ << std::endl; } }; void main() { std::cout << "from main():" << std::endl << __FUNCTION__ << std::endl << __func__ << std::endl << __FUNCSIG__ << std::endl << std::endl; A<int, float>::f<bool>(); }
输出:
从main(): 主要 主要 int __cdecl main(void) 来自A :: f(): A <整数,浮点> ::˚F F void __cdecl A <int,float> :: f&ltbool>(void)
按照预期,使用__PRETTY_FUNCTION__
会触发未声明的标识符错误。