I just found one post Conditional Compilation which can be better explained the differences between #if
/#elif
and #ifdef
/#ifndef
from syntax level:
#if constant-expression newline
#ifdef identifier newline
#ifndef identifier newline
#else newline
#elif constant-expression newline
#endif newline
So here we can see #ifndef
must be followed by 'identifier', that was often the macro defined by #define
directive, or @rmaddy said 'a single value'.
But if
can be followed by 'constant-expression' so that the conditional expression defined(INTERNATIONAL) || defined(DEBUG)
or !defined(INTERNATIONAL) && !defined(DEBUG)
can be used.