Search code examples
cmacrosidentifier

Macro name must be an identifier


please, tell me what's wrong with this code:

// part of main.c

#if have(some_macro)
    printf("Import succeeded!\n");
#else
#   error Import failed!
#endif

// part of utils.h

#define have(macro) defined(macro)

If I write just #if defined(some_macro) it works.
What's the problem?


Solution

  • You cannot have anything following #if expand to defined. That is subject to undefined behavior.

    From the C99 Standard (emphasis mine):

    6.10.1 Conditional inclusion

    ...

    3 Preprocessing directives of the forms

     # if *constant-expression new-line group<sub>opt</sub>*
     # elif *constant-expression new-line group<sub>opt</sub>*
    

    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.