Search code examples
cc-preprocessordocumentationtokenizepreprocessor

I can't wrap my head around this sentence from the GNU C PREPROCESSOR documentation


Link to the page

It is in the 9th row under the "tokenization" section in the "Preprocessor overview" It's as follows:

The only identifier which can be considered a preprocessing keyword is defined.

I tried

#define DEFINED

but it works just fine.

I also asked chatGPT and searched the web for it but nothing helped.

What does this tell us in practice? What limitations does this cause us?


Solution

  • First note that C is a case-sensitive language, so DEFINED and defined mean different things. What the text refers to is the special identifier defined only valid inside pre-processor macros. Usage is like this:

    #if defined(__STDC__) && (__STDC__VERSION == 201710L)
      puts("This C compiler is up to date.");
    #endif
    

    This is equivalent to:

    #ifdef __STDC__
      #if (__STDC__VERSION == 201710L)
        puts("This C compiler is up to date.");
      #endif
    #endif
    

    As we can see, the benefit of define is that it allows simpler pre-processor checks without resorting to multiple nested #if/#ifdef. Suppose we want to check of a compiler is following standard C and also supports VLA:

    #if defined(__STDC__) && !defined(__STDC_NO_VLA__)
      puts("This compiler is useful");
    #else
      puts("This compiler is useless");
    #endif
    

    That's a whole lot more convenient code with no code repetition, compared to this mess:

    #ifdef __STDC__
      #ifndef __STDC_NO_VLA__
        puts("This compiler is useful");
      #else
        puts("This compiler is useless");
      #endif
    #else
      puts("This compiler is useless");
    #endif