Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the difference between __PRETTY_FUNCTION__, __FUNCTION__, __func__?

People also ask

What is __ Pretty_function __?

The identifier __PRETTY_FUNCTION__ holds the name of the function pretty printed in a language specific fashion. These names are always the same in a C function, but in a C++ function they may be different. For example, this program: extern "C" { extern int printf (char *, ...

What is __ FILE __ in C++?

The __FILE__ macro expands to a string whose contents are the filename, surrounded by double quotation marks ( " " ). If you change the line number and filename, the compiler ignores the previous values and continues processing with the new values. The #line directive is typically used by program generators.

What is __ LINE __ in C?

__LINE__ is a preprocessor macro that expands to current line number in the source file, as an integer. __LINE__ is useful when generating log statements, error messages intended for programmers, when throwing exceptions, or when writing debugging code.

What are C++ macros?

Macros and its types in C/C++ A macro is a piece of code in a program that is replaced by the value of the macro. Macro is defined by #define directive. Whenever a macro name is encountered by the compiler, it replaces the name with the definition of the macro.


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

static 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."


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**)

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

I'll give it a try when support arrives to GCC, GCC 9.1.0 with g++-9 -std=c++2a still doesn't support it.

https://en.cppreference.com/w/cpp/utility/source_location claims usage will be like:

#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!");
}

Possible output:

info:main.cpp:16: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?


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


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&ltbool>(void)

Using of __PRETTY_FUNCTION__ triggers undeclared identifier error, as expected.