Why __FILE__ does not print the full path (even with gcc)

Summary

The __FILE__ macro in C/C++ does not inherently provide the full absolute path to the source file. Instead, it reflects the path as passed to the compiler during preprocessing. This behavior is independent of the compiler (gcc/g++) or language standard. The relative path issue arises from how the file is included or specified in the build process.

Root Cause

  • __FILE__ is preprocessor-dependent: It captures the file path exactly as it appears in the preprocessor’s input, not the absolute path.
  • Relative paths in build commands: If the file is included or compiled with a relative path (e.g., gcc -c ../Separate.c), __FILE__ will store that relative path.

Why This Happens in Real Systems

  • Build system design: Most build systems (e.g., Make, CMake) use relative paths for portability and simplicity.
  • Preprocessor limitations: The preprocessor does not resolve paths to absolute forms unless explicitly instructed.

Real-World Impact

  • Logging inconsistencies: Logs may contain relative paths, making it hard to trace files in large projects.
  • Debugging challenges: Relative paths can lead to confusion when source files are located in different directories.

Example or Code (if necessary and relevant)

#include 
int main(void) {
    printf("%s\n", __FILE__);
    return 0;
}

Explanation: Compiling with gcc -c ../Separate.c results in __FILE__ printing ../Separate.c because the relative path is passed to the preprocessor.

How Senior Engineers Fix It

  • Use absolute paths in build commands: Explicitly provide the full path to the source file during compilation.
  • Preprocess with -working-directory: Use gcc -working-directory=/full/path -E source.c to force the preprocessor to resolve paths relative to a specific directory.
  • Post-process logs: Programmatically resolve relative paths to absolute paths in the logging utility.

Why Juniors Miss It

  • Assumption of compiler magic: Juniors often assume the compiler automatically resolves paths to absolute forms.
  • Overlooking preprocessor behavior: The distinction between preprocessor and compiler behavior is frequently misunderstood.
  • Ignoring build system details: Relative paths in build scripts or commands are often overlooked as the root cause.

Leave a Comment