问题
I am compiling my code on many linux machines, on a specific machine, I receive the following error:
error: operator '&&' has no right operand
The macro code is:
#if LINUX_VERSION_CODE == KERNEL_VERSION(3,12,49) && KERNEL_PATCH_LEVEL == 11
where LINUX_VERSION_CODE and KERNEL_VERSION are defined in linux sources and KERNEL_PATCH_LEVEL is defined in my Makefile
KERNEL_PATCH_LEVEL :=$(word 1, $(subst ., ,$(word 2, $(subst -, ,$(KERNEL_HEADERS)))))
If i change the code to 2 different lines, like this, it works:
#if LINUX_VERSION_CODE == KERNEL_VERSION(3,12,49)
#if KERNEL_PATCH_LEVEL == 11
...
#endif //KERNEL_PATCH_LEVEL == 11
#endif
Is it possible to still keep it with one #if ? I use gcc version 4.9.0 (Debian 4.9.0-7)
The following macro does not work:
#if (LINUX_VERSION_CODE == KERNEL_VERSION(3,12,49)) && (KERNEL_PATCH_LEVEL == 11)
#if ((LINUX_VERSION_CODE == KERNEL_VERSION(3,12,49)) && (KERNEL_PATCH_LEVEL == 11))
#if defined(KERNEL_MAJOR) && defined(KERNEL_MINOR) && defined(KERNEL_MICRO) && defined(KERNEL_PATCH_LEVEL) && defined(KERNEL_VERSION) &&
defined(LINUX_VERSION_CODE) && \
(LINUX_VERSION_CODE == KERNEL_VERSION(3,12,49)) && (KERNEL_PATCH_LEVEL == 11)
回答1:
it turns out that the error source is that KERNEL_PATCH_LEVEL
is defined in the makefile but empty.
In that case, the 2 lines aren't equivalent, since
#if LINUX_VERSION_CODE == KERNEL_VERSION(3,12,49) && KERNEL_PATCH_LEVEL == 11
evaluates both parts no matter what the the outcome of the first test is, so the preprocessor stumbles on the syntax error when meeting && == 11
.
But if LINUX_VERSION_CODE == KERNEL_VERSION(3,12,49)
is false, with this construct:
#if LINUX_VERSION_CODE == KERNEL_VERSION(3,12,49)
#if KERNEL_PATCH_LEVEL == 11
...
#endif //KERNEL_PATCH_LEVEL == 11
#endif
you're not entering the first #if
so the inner #if
(which is wrong since worth #if == 11
) belongs to a block which skipped by the preprocessor, which explains that there's no error.
Note that if KERNEL_PATCH_LEVEL
is not defined, #if
sees that as 0
, that wouldn't have triggered any error.
you can protect against ill-defined KERNEL_PATCH_LEVEL
with this (seen in Test for empty macro definition, I have added a better answer now)
#if (KERNEL_PATCH_LEVEL + 0) == 0
#undef KERNEL_PATCH_LEVEL
#define KERNEL_PATCH_LEVEL 0
#endif
so if the macro is defined empty (or is 0), undefine it and define it to a 0
value. You could even detect (see my answer in the link above to understand how it works) if it's empty instead of 0
like this:
#if (0-KERNEL_PATCH_LEVEL-1)==1 && (KERNEL_PATCH_LEVEL+0)!=-2
#error "KERNEL_PATCH_LEVEL defined empty"
#endif
来源:https://stackoverflow.com/questions/48538243/macro-if-statement-returns-error-operator-has-no-right-operand