在预处理程序if语句中定义C宏

时间:2018-08-02 15:07:02

标签: c-preprocessor

下面,我根据INPUT的值来更改所调用函数的值:

#include <stdio.h>

#define INPUT second
#if INPUT == first
#define FUNCTOCALL(X) first(X)
#elif INPUT == second
#define FUNCTOCALL(X) second(X)
#endif

void first(int x) {
    printf("first %d\n", x);
}

void second(int x) {
    printf("second %d\n", x);
}

int main() {

    FUNCTOCALL(3);

    return 0;    
}

但是,即使INPUT等于秒,输出仍为first 3,如上所述。实际上,无论INPUT的值如何,总是输入第一个分支。我对此完全感到困惑-有人可以解释我正在犯什么愚蠢的错误吗?

2 个答案:

答案 0 :(得分:2)

c预处理器仅在其条件中处理整数常量表达式。 如果给它令牌,则它不能扩展(例如firstsecond不是宏的firstsecond) 会将其视为0,而0 == 0则是我上次使用数学时的真实值。这就是为什么总是采用第一个分支的原因。

6.10.1p4

  

...由于宏扩展和定义而进行所有替换之后   一元运算符已执行,其余所有标识符   (包括与关键字在词法上相同的关键字)替换为   pp-number 0,然后将每个预处理令牌转换为   令牌。 ...

答案 1 :(得分:1)

您没有定义 firstsecond。请注意,预处理器不知道C或C ++函数名称! * 在比较和计算(例如#if value#if 2*X == Y)中,宏未定义(未定义)或根本没有定义)或没有值的情况下求值为0。因此,由于未定义firstsecond,因此INPUT被定义为没有值,并且两个{{1 }}表达式的取值为#if ...

但是,如果您 did 根据需要定义了两个宏,则它们将与C函数名称冲突,并且预处理器会将它们替换为您刚定义它们时的宏值。导致代码无效(例如,名为0 == 01的函数)...

您可以尝试以下方法:

2

请注意大小写的差异,从而使宏和函数名称不同。

*更准确地说,预处理器不知道任何 C或C ++标记,因此它不了解int,double,struct或classes等类型。 .. –它所知道的就是您使用#define INPUT SECOND #define FIRST 1 #define SECOND 2 #if INPUT == FIRST #define FUNCTOCALL(X) first(X) #elif INPUT == SECOND #define FUNCTOCALL(X) second(X) #else # error INPUT not defined #endif 明确知道的内容,其他所有内容都是它在其上操作的文本,如果遇到某些已知的文本节点,请用您定义的内容替换它们。 < / p>