C++ Predefined Macros: FILE, LINE, and func

Predefined macros and identifiers such as __FILE__, __LINE__, and __func__ provide access to source code metadata during compilation and execution in C++. These tools automatically capture the file name, line number, and function name where they are invoked, making them indispensable for debugging, automated logging, error reporting, and runtime diagnostics.

Core Definitions

  • __FILE__: A standard preprocessor macro that expands to a string literal containing the path and name of the current source file being compiled.
  • __LINE__: A standard preprocessor macro that expands to an integer representing the current line number within the source file.
  • __func__: Standardized in C++11 (and C99), __func__ is technically a predefined local variable rather than a preprocessor macro. It is implicitly defined at the beginning of every function as static const char __func__[] = "function-name";, containing the unmangled name of the enclosing function.

Primary Use Cases

1. Context-Rich Logging

Standard log statements often state what happened, but not where. Using these identifiers injects precise code locations into log output, eliminating the guesswork during post-mortem analysis.

#define LOG_INFO(msg) \
    std::cout << "[INFO] (" << __FILE__ << ":" << __LINE__ \
              << " in " << __func__ << "): " << msg << '\n'

2. Assertions and Error Handling

Custom assertion mechanisms rely heavily on these macros to pinpoint the failure point when a critical assumption in the code is violated. If an assertion fails, the output can explicitly display the exact file, line, and function without requiring an interactive debugger.

#define CUSTOM_ASSERT(condition) \
    do { \
        if (!(condition)) { \
            std::cerr << "Assertion failed: (" #condition ") at " \
                      << __FILE__ << ":" << __LINE__ \
                      << " in " << __func__ << '\n'; \
            std::abort(); \
        } \
    } while (0)

3. Exception Metadata

When throwing custom exceptions, embedding __FILE__, __LINE__, and __func__ into the exception object preserves the call site information. This allows top-level exception handlers to log exactly where the error originated, even after the stack has unwound.

Key Distinctions

While __FILE__ and __LINE__ are substituted directly by the preprocessor before the code is compiled, __func__ is handled during semantic analysis by the compiler. Because __func__ is aware of language scopes, it cannot be used for preprocessor string concatenation (such as "Error in " __FILE__), but it reliably returns the current function context regardless of preprocessor phase limitations.