What's the difference between __PRETTY_FUNCTION__, __FUNCTION__, __func__?
Solution 1
__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:
The identifier
__func__
is implicitly declared by the translator as if, immediately following the opening brace of each function definition, the declarationstatic const char __func__[] = "function-name";
appeared, where function-name is the name of the lexically-enclosing function. This name is the unadorned name of the function.
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."
Solution 2
Despite not fully answering the original question, this is probably what most people googling this wanted to see.
For GCC:
$ cat test.cpp
#include <iostream>
int main(int argc, char **argv)
{
std::cout << __func__ << std::endl
<< __FUNCTION__ << std::endl
<< __PRETTY_FUNCTION__ << std::endl;
}
$ g++ test.cpp
$ ./a.out
main
main
int main(int, char**)
Solution 3
__PRETTY_FUNCTION__
handles C++ features: classes, namespaces, templates and overload
main.cpp
#include <iostream>
namespace N {
class C {
public:
template <class T>
static void f(int i) {
(void)i;
std::cout << "__func__ " << __func__ << std::endl
<< "__FUNCTION__ " << __FUNCTION__ << std::endl
<< "__PRETTY_FUNCTION__ " << __PRETTY_FUNCTION__ << std::endl;
}
template <class T>
static void f(double f) {
(void)f;
std::cout << "__PRETTY_FUNCTION__ " << __PRETTY_FUNCTION__ << std::endl;
}
};
}
int main() {
N::C::f<char>(1);
N::C::f<void>(1.0);
}
Compile and run:
g++ -ggdb3 -O0 -std=c++11 -Wall -Wextra -pedantic -o main.out main.cpp
./main.out
Output:
__func__ f
__FUNCTION__ f
__PRETTY_FUNCTION__ static void N::C::f(int) [with T = char]
__PRETTY_FUNCTION__ static void N::C::f(double) [with T = void]
You may also be interested in stack traces with function names: print call stack in C or C++
Tested in Ubuntu 19.04, GCC 8.3.0.
C++20 std::source_location::function_name
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1208r5.pdf went into C++20, so we have yet another way to do it.
The documentation says:
constexpr const char* function_name() const noexcept;
6 Returns: If this object represents a position in the body of a function, returns an implementation-defined NTBS that should correspond to the function name. Otherwise, returns an empty string.
where NTBS means "Null Terminated Byte String".
The feature is present on GCC 11.2 Ubuntu 21.10 with -std=c++20
. It was not on GCC 9.1.0 with g++-9 -std=c++2a
.
https://en.cppreference.com/w/cpp/utility/source_location shows usage is:
main.cpp
#include <iostream>
#include <string_view>
#include <source_location>
void log(std::string_view message,
const std::source_location& location = std::source_location::current()
) {
std::cout << "info:"
<< location.file_name() << ":"
<< location.line() << ":"
<< location.function_name() << " "
<< message << '\n';
}
int main() {
log("Hello world!");
}
Compile and run:
g++ -std=c++20 -Wall -Wextra -pedantic -o main.out main.cpp
./main.out
Output:
info:main.cpp:17:int main() Hello world!
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?
Solution 4
__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:
static const char __func__[] = "function-name ";
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++0x
g++ -std=c++98 ....
will 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.
Solution 5
For those, who wonder how it goes in VS.
MSVC 2015 Update 1, cl.exe version 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>();
}
output:
from main(): main main int __cdecl main(void) from A::f(): A<int,float>::f f void __cdecl A<int,float>::f<bool>(void)
Using of __PRETTY_FUNCTION__
triggers undeclared identifier error, as expected.
Related videos on Youtube
Matt Joiner
About Me I like parsimonious code, with simple interfaces and excellent documentation. I'm not interested in enterprise, boiler-plate, or cookie-cutter nonsense. I oppose cruft and obfuscation. My favourite languages are Go, Python and C. I wish I was better at Haskell. Google+ GitHub Bitbucket Google code My favourite posts http://stackoverflow.com/questions/3609469/what-are-the-thread-limitations-when-working-on-linux-compared-to-processes-for/3705919#3705919 http://stackoverflow.com/questions/4352425/what-should-i-learn-first-before-heading-to-c/4352469#4352469 http://stackoverflow.com/questions/6167809/how-much-bad-can-be-done-using-register-variables-in-c/6168852#6168852 http://stackoverflow.com/questions/4141307/c-and-c-source-code-profiling-tools/4141345#4141345 http://stackoverflow.com/questions/3463207/how-big-can-a-malloc-be-in-c/3486163#3486163 http://stackoverflow.com/questions/4095637/memory-use-of-stl-data-structures-windows-vs-linux/4183178#4183178
Updated on December 28, 2021Comments
-
Matt Joiner over 2 years
What's the difference between
__PRETTY_FUNCTION__
,__FUNCTION__
,__func__
, and where are they documented? How do I decide which one to use? -
James McNellis over 13 years
__func__
is not part of C++03. It has been added in C++0x, but C++0x is not yet "the C++ standard," it is still in draft form. -
Matt Joiner over 13 yearsCan you link to the C99 specification (there's a floating link in your source), for what looks like the winning answer?
-
James McNellis over 13 years@Matt: Sure. I added a link to the latest C++0x draft with paragraph reference as well, just so everything has a good reference.
-
James McNellis almost 11 years@legends2k: No, it is "an implementation-defined string" in C++11. That's the actual language from the specification. See §8.4.1[dcl.fct.def.general]/8.
-
daramarak over 10 years@JamesMcNellis It is now, so clear the comments, to remove the noise
-
Doncho Gunchev over 9 yearsSame output from clang 3.5
-
Adrian McCarthy almost 9 yearsNote that while both gcc and VC provide
__FUNCTION__
, they do slightly different things. gcc gives the equivalent of__func__
. VC gives the undecorated, but still adorned, version of the name. For a method named "foo", gcc will give you"foo"
, VC will give"my_namespace::my_class::foo"
. -
4LegsDrivenCat over 8 yearsMSVC provides one more non-standard predefined macro -
__FUNCDNAME__
- the decorated name of the enclosing function. -
Francis Cugler almost 7 yearsMSVC also has another that shows the functions memory address in hex format:
__FUNCTIONW__
-
Francis Cugler almost 7 yearsWhat is curious is that I am using MSVC 2017 CE and when I type
__PRETTY_FUNCTION__
it does show up in the list as being available and when I move my mouse over it, it does display information about the function name, however it does fail to compile. -
MarcusJ over 6 yearsOk, but does
__func__
work when it's embedded in another function? Lets say I have function1, it takes no arguments. function1 calls function2 that includes__func__
, which function name will be printed, 1 or 2? -
Petr over 6 years@MarcusJ why not try it yourself... the
__func__
is a macro, it will translate to whatever function you are currently in. If you put it into f1 and call f1 in f2, you will always get f1. -
MarcusJ over 6 yearsI was going to, then thought I'd ask. I feel like it won't work and it's kind of a pain in the ass so I'll just keep it the way it is.
-
Adam Badura about 6 years@FrancisCugler I was surprised by this as well! See my question on it stackoverflow.com/questions/48857887/…
-
John P over 3 yearsI have a little macro that detects the compiler and uses either
__PRETTY_FUNCTION__
or__FUNCSIG__
, but I'd like to support a few more compilers if at all possible. Do any other compilers have a function signature macro, especially with template parameters? Edit - so far Clang, GCC, MSVC -
Keith Thompson over 2 years@Petr Strictly speaking
__func__
is a predefined identifier, not a macro. -
Xeverous about 2 years
void main()
is technically ill-formed.main
, however defined in terms of arguments must returnint
.