Standard Predefined Macros for Build Metadata in C

The C programming language provides several standard predefined macros that inject essential compile-time metadata directly into your source code. These macros capture information such as source file paths, line numbers, and compilation timestamps, allowing developers to create diagnostic logs, track releases, and inspect compiler conformance without manual intervention.

Core Build Metadata Macros

The ISO C standard mandates several predefined macros that are expanded by the preprocessor during compilation:

  • __FILE__: Expands to a string literal containing the name (and often the path) of the current source file being compiled.
  • __LINE__: Expands to an integer constant representing the current line number within the source file.
  • __DATE__: Expands to a string literal containing the compilation date in the format "Mmm dd yyyy" (for example, "Apr 12 2024").
  • __TIME__: Expands to a string literal containing the compilation time in the format "hh:mm:ss".
  • __TIMESTAMP__: A common non-standard extension (supported by GCC, Clang, and MSVC) that expands to the date and time of the last modification of the current source file as a string literal (e.g., "Fri Apr 12 14:32:01 2024").

Environmental and Conformance Macros

Beyond source locations and timestamps, standard macros provide information about the compilation environment:

  • __STDC__: Defined as 1 if the compiler conforms to ISO C standards.
  • __STDC_VERSION__: Expands to a long integer indicating the specific standard version the compiler supports (e.g., 199901L for C99, 201112L for C11, or 201710L for C17).
  • __STDC_HOSTED__: Expands to 1 if the program is being compiled for a hosted environment (with standard library support), or 0 for a freestanding environment (often embedded systems).

Common Use Cases

1. Contextual Logging and Error Handling

Combining __FILE__ and __LINE__ allows developers to pinpoint where an event, warning, or assertion failure occurred.

#include <stdio.h>

#define LOG_ERROR(msg) fprintf(stderr, "[ERROR] %s:%d: %s\n", __FILE__, __LINE__, msg)

int main(void) {
    LOG_ERROR("Unable to allocate memory");
    return 0;
}

Note: In C99 and later, the predefined identifier __func__ can also be combined with these macros to output the enclosing function name.

2. Build Information and Version Strings

__DATE__ and __TIME__ are frequently embedded into binaries to display build information in CLI utilities or firmware banners.

#include <stdio.h>

void print_version(void) {
    printf("Application v1.0.0 (Built: %s %s)\n", __DATE__, __TIME__);
}

Reproducible Builds Consideration

While __DATE__ and __TIME__ are widely used for build auditing, they introduce non-deterministic variations between consecutive builds of the same source code. To support reproducible builds, modern compilers like GCC and Clang honor the SOURCE_DATE_EPOCH environment variable, which causes __DATE__ and __TIME__ to be generated from a fixed Unix timestamp rather than the current system clock.