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