宏if语句返回错误:operator'&&'没有正确的操作数

时间:2018-01-31 09:03:44

标签: c macros c-preprocessor

我正在许多linux机器上编译我的代码,在特定的机器上,我收到以下错误:

error: operator '&&' has no right operand

宏代码是:

#if LINUX_VERSION_CODE == KERNEL_VERSION(3,12,49) && KERNEL_PATCH_LEVEL == 11

其中LINUX_VERSION_CODE和KERNEL_VERSION在linux源代码中定义,KERNEL_PATCH_LEVEL在我的Makefile中定义

KERNEL_PATCH_LEVEL :=$(word 1, $(subst ., ,$(word 2, $(subst -, ,$(KERNEL_HEADERS)))))

如果我将代码更改为2个不同的行,就像这样可行

#if LINUX_VERSION_CODE == KERNEL_VERSION(3,12,49) 
#if KERNEL_PATCH_LEVEL == 11
  ...
#endif //KERNEL_PATCH_LEVEL == 11
#endif 

是否可以保留一个#if? 我使用gcc版本4.9.0(Debian 4.9.0-7)

以下宏不起作用:

#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 个答案:

答案 0 :(得分:2)

事实证明,错误源是makefile中定义KERNEL_PATCH_LEVEL但是为空。

在这种情况下,2行不等同,因为

#if LINUX_VERSION_CODE == KERNEL_VERSION(3,12,49) && KERNEL_PATCH_LEVEL == 11
无论第一次测试的结果是什么,

都会评估这两个部分,因此预处理器在遇到&& == 11时会遇到语法错误。

但如果LINUX_VERSION_CODE == KERNEL_VERSION(3,12,49)为假,则使用此结构:

#if LINUX_VERSION_CODE == KERNEL_VERSION(3,12,49) 
#if KERNEL_PATCH_LEVEL == 11
  ...
#endif //KERNEL_PATCH_LEVEL == 11
#endif 

您没有输入第一个#if,因此内部#if(由于值#if == 11这是错误的)属于预处理器跳过的块,这解释了没有错误。

请注意,如果未定义KERNEL_PATCH_LEVEL#if会将其视为0,则不会触发任何错误。

您可以使用此功能防止定义不明确KERNEL_PATCH_LEVEL(见Test for empty macro definition,我现在添加了更好的答案)

#if (KERNEL_PATCH_LEVEL + 0) == 0
#undef KERNEL_PATCH_LEVEL
#define KERNEL_PATCH_LEVEL 0
#endif

因此,如果将宏定义为空(或为0),则取消定义它并将其定义为0值。如果它是空的而不是0,您甚至可以检测到(请参阅上面链接中的答案以了解其工作原理):

#if (0-KERNEL_PATCH_LEVEL-1)==1 && (KERNEL_PATCH_LEVEL+0)!=-2
#error "KERNEL_PATCH_LEVEL defined empty"
#endif