Comprehensive Analysis of __PRETTY_FUNCTION__, __FUNCTION__, and __func__ in C/C++ Programming

Nov 28, 2025 · Programming · 25 views · 7.8

Keywords: C++ | C Programming | Function Name Identifiers | Compiler Extensions | Debugging Techniques

Abstract: This technical article provides an in-depth comparison of the function name identifiers __PRETTY_FUNCTION__, __FUNCTION__, and __func__ in C/C++ programming. It examines their standardization status, compiler support, and practical usage through detailed code examples. The analysis covers C99 and C++11 standards, GCC and Visual C++ extensions, and the modern C++20 std::source_location feature, offering guidance on selection criteria and best practices for different programming scenarios.

Overview of Function Name Identifiers

In C/C++ programming, obtaining the current function name is a common requirement for debugging and logging purposes. The language standards and compilers provide various mechanisms to achieve this functionality. Among these, __func__, __FUNCTION__, and __PRETTY_FUNCTION__ are the most commonly used identifiers. While these identifiers share overlapping functionality, they exhibit significant differences in standardization, compiler support, and output format.

Standard Identifier: __func__

__func__ is the official identifier introduced in the C99 standard and subsequently adopted in C++11. According to C99 standard §6.4.2.2/1, the compiler implicitly declares at the beginning of each function definition:

static const char __func__[] = "function-name";

where function-name is the name of the lexically-enclosing function, representing the unadorned function name. It is important to note that __func__ is not a macro and has no special meaning during preprocessing.

In C++11, __func__ is specified as containing an "implementation-defined string" (C++11 §8.4.1[dcl.fct.def.general]/8), which is somewhat less specific than the C standard specification and may lead to implementation variations across different compilers.

Compiler Extension: __FUNCTION__

__FUNCTION__ is a pre-standard extension supported by major compilers including GCC and Visual C++. Functionally, it is largely equivalent to __func__, returning the simple function name. However, since __FUNCTION__ is not part of any standard, its behavior may vary between compilers.

In practice, it is recommended to prioritize the standardized __func__ and consider using __FUNCTION__ only when working with compilers that lack C99/C++11 support. For instance, early versions of Visual C++ that did not support C99 made __FUNCTION__ a viable alternative for obtaining function names.

Enhanced Extension: __PRETTY_FUNCTION__

__PRETTY_FUNCTION__ is a GCC-specific extension that provides richer function information in C++ environments. Unlike __FUNCTION__ and __func__, which return only the simple function name, __PRETTY_FUNCTION__ returns a "pretty" name containing detailed information such as function signatures, class names, and namespaces.

Consider the following C++ template function example:

namespace N {
    class C {
        public:
            template <class T>
            static void f(int i) {
                std::cout << "__func__: " << __func__ << std::endl;
                std::cout << "__FUNCTION__: " << __FUNCTION__ << std::endl;
                std::cout << "__PRETTY_FUNCTION__: " << __PRETTY_FUNCTION__ << std::endl;
            }
    };
}

When calling N::C::f<char>(1), the output would be:

__func__: f
__FUNCTION__: f
__PRETTY_FUNCTION__: static void N::C::f(int) [with T = char]

This feature makes __PRETTY_FUNCTION__ particularly valuable when dealing with function overloading, template specialization, and complex class hierarchies.

Compiler Compatibility Considerations

Different compilers exhibit varying levels of support for these identifiers. GCC provides comprehensive support for all three identifiers, while Visual C++ offers a similar extension __FUNCSIG__ that functions similarly to __PRETTY_FUNCTION__ but with some differences.

For projects requiring cross-compiler compatibility, a conditional compilation approach is recommended:

#if defined(__GNUC__) || defined(__clang__)
    #define CURRENT_FUNCTION __PRETTY_FUNCTION__
#elif defined(_MSC_VER)
    #define CURRENT_FUNCTION __FUNCSIG__
#else
    #define CURRENT_FUNCTION __func__
#endif

C++20 Modern Feature: std::source_location

C++20 introduces the std::source_location class, providing a more standardized approach to obtaining source code location information, including function names. Its function_name() member function returns an implementation-defined null-terminated byte string corresponding to the function name.

Example usage:

#include <source_location>

void log(const std::string& message,
         const std::source_location& location = std::source_location::current()) {
    std::cout << "Function: " << location.function_name() << " - " << message << std::endl;
}

This feature is particularly suitable for logging and debugging tools, as it automatically captures caller function information.

Selection Strategy and Best Practices

When choosing which function name identifier to use, consider the following factors:

  1. Standardization: Prioritize the standardized __func__ to ensure code portability.
  2. Information Requirements: For detailed function signature information, use __PRETTY_FUNCTION__ in GCC environments and __FUNCSIG__ in Visual C++.
  3. Compiler Compatibility: For projects supporting multiple compilers, employ conditional compilation or feature detection mechanisms.
  4. C++ Version: In C++20 and later, consider using std::source_location as a more modern alternative.

Practical Application Scenarios

These function name identifiers are particularly useful in the following scenarios:

By appropriately selecting and utilizing these identifiers, developers can significantly enhance code debuggability and maintainability while ensuring compatibility across different compilation environments.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.