Search code examples
cc89

C Standard Version Check


  • Platform: Ubuntu 14.04 LTS
  • Compiler: GCC 4.8.2 (Ubuntu 4.8.2-19ubuntu1)

I am writing a header that needs to be backwards complaint with C90. I have some optional functions that are included if the complier supports C99 or C11. So I use the standard feature test macros. I just want to know if the way I do this is correct.

#if __STDC__
   //code
#endif

#if __STDC_VERSION__ >= 199000L
    //code
#endif

#if __STDC_VERSION__ >= 201100L
   //code
#endif

I am assuming that if the compiler is strictly C90 or C89 then the compiler will error out and say __STDC_VERSION__ is undefined am I correct? If so should I use defined()? For example #if defined(__STDC__) rather than just #if __STDC__.


Solution

  • Undefined identifiers in preprocessor-conditionals are replaced by 0 if they are not argument to define, thus no error:

    6.10.1 Conditional inclusion

    3 Preprocessing directives of the forms

    #if constant-expression new-line groupopt
    #elif constant-expression new-line groupopt
    

    check whether the controlling constant expression evaluates to nonzero.
    4 Prior to evaluation, macro invocations in the list of preprocessing tokens that will become the controlling constant expression are replaced (except for those macro names modified by the defined unary operator), just as in normal text. If the token defined is generated as a result of this replacement process or use of the defined unary operator does not match one of the two specified forms prior to macro replacement, the behavior is undefined. After all replacements due to macro expansion and the defined unary operator have been performed, all remaining identifiers (including those lexically identical to keywords) are replaced with the pp-number 0, and then each preprocessing token is converted into a token. [...]

    You can use the #error directive to force a compilation-error.