During one review I came across a piece of code like the following :
#if defined(x) || y
What does the above statement mean ? Will the condition execute properly ?
4 Answers
Yes it is valid.
Here is what the Standard (C99) says in 6.10p1:
if-group:
# if constant-expression new-line groupopt
# ifdef identifier new-line groupopt
# ifndef identifier new-line groupopt
the defined operator is seen as unary operator part of a constant expression (6.10.1p1).
In your example, the condition is evaluated as true if the macro x is defined OR if y is defined and different than 0
The reasoning for this is twofold.
Instead of using a #ifdef, you use the defined operator so that you can use logical operators on it (&&, ||, etc.), so that you don't have to duplicate your code so that it is included properly if there is multiple criteria for what you need to defined.
Also, in my opinion, I find it much easier to read as #if defined(x) than #ifdef x, and you could do the following #if defined(x) && defined(y), whereas that isn't possible with #ifdef.
Yes, since defined(x) is a boolean and returns true or false.
The above statement means "either x is defined or y is true".
it is correct but it is a bad practice. Why use two different evaluations ('y' and 'defined(x)') in one conditional. It might be confusing for others. The example below shows more common use of || and && operatiors against #defined macros:
#define AA 1
#define BB 2
#if (defined AA) || (defined BB)
#warning "A or B"
#endif
#if (defined AA) && (defined BB)
#warning "A and B"
#endif
When the above code was run user would get these messages on screen:
#warning "A or B"
#warning "A and B"
But if code was like this (AA was undefined):
#undefine AA
#define BB 2
#if (defined AA) || (defined BB)
#warning "A or B"
#endif
#if (defined AA) && (defined BB)
#warning "A and B"
#endif
then user will get this message:
#warning "A or B"