macro if statement returns error: operator '&&' has no right operand

喜欢而已 提交于 2019-12-23 12:23:04

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!