__PRETTY_FUNCTION__、__FUNCTION__、__func__ 之间有什么区别?
__PRETTY_FUNCTION__
、__FUNCTION__
、__func__
之间有什么区别,它们的记录在哪里?我如何决定使用哪一个?
What's the difference between __PRETTY_FUNCTION__
, __FUNCTION__
, __func__
, and where are they documented? How do I decide which one to use?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
__func__
是一个隐式声明的标识符,当在函数内部使用时,它会扩展为包含函数名称的字符数组变量。它在 C99 中被添加到 C 中。来自 C99 §6.4.2.2/1:请注意,它不是宏,并且在预处理期间没有特殊含义。
__func__
在 C++11 中被添加到 C++,其中它被指定为包含“实现定义的字符串”(C++11 §8.4.1[dcl.fct.def.general]/ 8),它不像 C 中的规范那么有用。(将__func__
添加到 C++ 的原始提议是 N1642)。__FUNCTION__
是一些 C 编译器(包括 gcc 和 Visual C++)支持的预标准扩展;一般来说,您应该在受支持的地方使用 __func__,并且仅在使用不支持它的编译器(例如,Visual C++,它不支持该功能)时才使用__FUNCTION__
支持C99,尚不支持所有C++0x,不提供__func__
)。__PRETTY_FUNCTION__
是一个 gcc 扩展,与__FUNCTION__
基本相同,但对于 C++ 函数,它包含函数的“漂亮”名称,包括函数的签名。 Visual C++ 有一个类似(但不完全相同)的扩展,__FUNCSIG__
。对于非标准宏,您需要查阅编译器的文档。 Visual C++ 扩展包含在 C++ 编译器的 “预定义宏” 的 MSDN 文档中。 gcc 文档扩展在 gcc 文档页面 “函数名称作为字符串”中进行了描述。 /a>
__func__
is an implicitly declared identifier that expands to a character array variable containing the function name when it is used inside of a function. It was added to C in C99. From C99 §6.4.2.2/1:Note that it is not a macro and it has no special meaning during preprocessing.
__func__
was added to C++ in C++11, where it is specified as containing "an implementation-defined string" (C++11 §8.4.1[dcl.fct.def.general]/8), which is not quite as useful as the specification in C. (The original proposal to add__func__
to C++ was N1642).__FUNCTION__
is a pre-standard extension that some C compilers support (including gcc and Visual C++); in general, you should use__func__
where it is supported and only use__FUNCTION__
if you are using a compiler that does not support it (for example, Visual C++, which does not support C99 and does not yet support all of C++0x, does not provide__func__
).__PRETTY_FUNCTION__
is a gcc extension that is mostly the same as__FUNCTION__
, except that for C++ functions it contains the "pretty" name of the function including the signature of the function. Visual C++ has a similar (but not quite identical) extension,__FUNCSIG__
.For the nonstandard macros, you will want to consult your compiler's documentation. The Visual C++ extensions are included in the MSDN documentation of the C++ compiler's "Predefined Macros". The gcc documentation extensions are described in the gcc documentation page "Function Names as Strings."
尽管没有完全回答最初的问题,但这可能是大多数在谷歌上搜索的人想看到的。
对于海湾合作委员会:
Despite not fully answering the original question, this is probably what most people googling this wanted to see.
For GCC:
__PRETTY_FUNCTION__
处理 C++ 功能:类、命名空间、模板和重载main.cpp
编译并运行:
输出:
您可能还对带有函数名称的堆栈跟踪感兴趣:如何在调用某个函数时打印堆栈跟踪
已测试在 Ubuntu 19.04、GCC 8.3.0 中。
C++20
std::source_location::function_name
main.cpp
编译并运行:
输出:
因此请注意它如何返回调用者信息,因此非常适合在日志记录,另请参阅: 是有没有办法在 C++ 函数中获取函数名称?
提案:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1208r5.pdf
该文档说:
其中 NTBS 表示“空终止字节字符串”。
在 GCC 11.3 Ubuntu 22.04 上测试。它不在带有
g++-9 -std=c++2a
的 GCC 9.1.0 上。__PRETTY_FUNCTION__
handles C++ features: classes, namespaces, templates and overloadmain.cpp
Compile and run:
Output:
You may also be interested in stack traces with function names: How to print a stack trace whenever a certain function is called
Tested in Ubuntu 19.04, GCC 8.3.0.
C++20
std::source_location::function_name
main.cpp
Compile and run:
Output:
so note how this returns the caller information, and is therefore perfect for usage in logging, see also: Is there a way to get function name inside a C++ function?
The proposal: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1208r5.pdf
The documentation says:
where NTBS means "Null Terminated Byte String".
Tested on GCC 11.3 Ubuntu 22.04. It was not on GCC 9.1.0 with
g++-9 -std=c++2a
.__func__
记录在 C++0x 标准的第 8.4.1 节中。在本例中,它是以下形式的预定义函数局部变量:其中“函数名称”是特定于实现的。这意味着每当您声明一个函数时,编译器都会将此变量隐式添加到您的函数中。
__FUNCTION__
和__PRETTY_FUNCTION__
也是如此。尽管它们是大写的,但它们不是宏。尽管__func__
是 C++0x 的补充,但仍将使用
__func__
编译代码。__PRETTY_FUNCTION__
和__FUNCTION__
记录在此处 http://gcc.gnu.org/onlinedocs/gcc-4.5.1/gcc/Function-Names.html#Function-Names。__FUNCTION__
只是__func__
的另一个名称。__PRETTY_FUNCTION__
与 C 中的__func__
相同,但在 C++ 中它也包含类型签名。__func__
is documented in the C++0x standard at section 8.4.1. In this case it's a predefined function local variable of the form:where "function name" is implementation specfic. This means that whenever you declare a function, the compiler will add this variable implicitly to your function. The same is true of
__FUNCTION__
and__PRETTY_FUNCTION__
. Despite their uppercasing, they aren't macros. Although__func__
is an addition to C++0xwill still compile code using
__func__
.__PRETTY_FUNCTION__
and__FUNCTION__
are documented here http://gcc.gnu.org/onlinedocs/gcc-4.5.1/gcc/Function-Names.html#Function-Names.__FUNCTION__
is just another name for__func__
.__PRETTY_FUNCTION__
is the same as__func__
in C but in C++ it contains the type signature as well.对于那些想知道 VS 中的情况如何的人。
MSVC 2015 Update 1,cl.exe 版本 19.00.24215.1:
输出:
使用
__PRETTY_FUNCTION__
会触发未声明的标识符错误,如预期的那样。For those, who wonder how it goes in VS.
MSVC 2015 Update 1, cl.exe version 19.00.24215.1:
output:
Using of
__PRETTY_FUNCTION__
triggers undeclared identifier error, as expected.