Search code examples
c++cmacrosc-preprocessor

Is #define X defined(Y) a valid C/C++ macro definition?


I read somewhere that

#define X defined(Y)

was invalid, but it seems to work.

Here is an example:

#define WIN_PLAT defined(_WIN32)

#if WIN_PLAT
#    undef  WIN_PLAT
#    define WIN_PLAT 1
#else
#    undef  WIN_PLAT
#    define WIN_PLAT 0
#endif

Solution

  • When a macro in a #if directive generates a defined token, the behavior is not defined by the C standard, per C 2018 6.10.1 4:

    … 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…

    Since the behavior is undefined, a compiler is free to support it, and a compiler is free not to support it. Therefore, you cannot rely on it generally.

    To implement #define X defined(Y), you can use:

    #if defined Y
        #define X 1
    #else
        #define X 0
    #endif
    

    (This differs from the original intent in that this will set X based on whether Y is defined at the point where this macro X is defined, not where it is replaced.)

    C++ has the same limitation. C++ 2020 draft N4849 15.2 [cpp.cond] 10 says:

    … 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.