Fun with Preprocessor Names

Your probably familiar with the #include and #define preprocessor directives. You may know a few more, which come in handy for certain coding issues. I have a page on this blog, which goes over some of the common directives, but it doesn’t cover them all. Specifically, it doesn’t cover the preprocessor names.

Preprocessor names are wonderful assistants, especially when it comes to debugging your code. They give you the same power that smart compilers (such as clang) have when it comes to pinpointing issues within a source code file.

For example, the __LINE__ macro expands into the specific line number in a source code file where it appears:

#include <stdio.h>

int main()
{
    printf("This is line %d\n",__LINE__);
    return(0);
}

The __LINE__ macro is used in Line 5 in the source code file. At compile time, it’s translated into the constant for the current line number, which is reflected in the program’s output:

This is line 5

Unlike other preprocessor directives, preprocessor names aren’t prefixed with a hash character, though they are embraced by double underscores. They need not appear on a line by themselves. They act more like constant expressions, though the values they report are related to items in the source code file.

In this code, I show all five of the predefined name macros in the ANSI C standard:

#include <stdio.h>

int main()
{
    printf("This file is named %s\n",__FILE__);
    printf("It was compiled on %s at %s\n",
            __DATE__,
            __TIME__
          );
    printf("Here is the STDC constant: %d\n",__STDC__);
    printf("This is line %d\n",__LINE__);
    return(0);
}

Along with __LINE__ to show the source code line, __FILE__ gives the source code filename, and __DATE__ and __TIME__ give the timestamp when the code was compiled. The __STDC__ value is 1 when the compiler supports ISO Standard C.

Here’s a sample run:

This file is named 0929b.c
It was compiled on Sep 15 2018 at 10:41:52
Here is the STDC constant: 1
This is line 11

By the way, you use the #line preprocessor directive to alter the value reported by the __LINE__ macro. I’m not certain why you’d want to do such a thing, but the option is available:

#include <stdio.h>

int main()
{
#line 86
    printf("This is line %d\n",__LINE__);
    return(0);
}

And the output:

This is line 86

The #line directive renumbers all subsequent lines. This change affects both the __LINE__ macro as well as any errors reported by the compiler. Of course, you can use #line again to reset the number, but then you’re just being crazy.

Leave a Reply