C预处理器#if表达式

17

我对在C语言中使用#IF预处理器可以使用的表达式类型有些困惑。我尝试了下面的代码,但它没有起作用。请解释并提供可以与预处理器一起使用的表达式示例。

#include<stdio.h>
#include<conio.h>
#include<stdlib.h>

int c=1;

#if c==1
    #define check(a) (a==1)?a:5
    #define TABLE_SIZE 100
#endif

int main()
{
    int a = 0, b;
    printf("a = %d\n", a);
    b = check(a);
    printf("a = %d %d\n", a, TABLE_SIZE);
    system("PAUSE");
    return 0;
}

一本C标准的副本或任何好书难道不能提供答案吗?例如,可以在Google上搜索“N1570”以找到C11标准的最新草案的免费副本。 - gnasher729
4个回答

30

预处理器不能在表达式中使用C程序中的变量 - 它只能操作预处理器宏。因此,当您尝试在预处理器中使用c时,您得到的结果可能不是您所期望的。

然而,您也不会收到错误提示,因为当预处理器试图计算未定义为宏的标识符时,它将该标识符视为具有零值。

因此,当您遇到这个片段时:

#if c==1
#define check(a) (a==1)?a:5
#define TABLE_SIZE 100
#endif

预处理器中使用的 c 和C程序中的变量 c 没有任何关系。预处理器会查看是否定义了宏 c,由于未定义,它会计算下面的表达式:

#if 0==1

这显然是错误的。

由于你在程序中似乎没有使用变量c,你可以采取以下方法来使行为符合你的要求:

#define C 1

#if C==1
#define check(a) (a==1)?a:5
#define TABLE_SIZE 100
#endif

(注意,我还按照宏名称的惯例将其大写。)


GCC和其他兼容GCC的编译器支持“-Wundef”选项,以在预处理器表达式中使用标识符时打开警告。这可以帮助防止涉及此预处理器功能的意外事件。 - jtchitty

5

在进行任何编译之前,预处理器会对文本进行处理。它不知道如何解析C语言。您可能想要的是int c = 1;代替。

#define C 1

测试按照你的要求进行了,并且成功了:

#if C == 1

关键在于所有这些都在编译时之前定义。预处理器不关心C变量,当然也不关心它们的值。

请注意,惯例是将预处理器宏定义为所有字母大写


0
预处理器不会评估 C 变量。它在编译之前“预处理”源代码,因此具有自己的语言。请改为:
#define c 1

#if c==1
#define check(a) (a==1)?a:5
#define TABLE_SIZE 100
#endif
...

0
在你的例子中,c 是编译器生成的符号,在运行时之前,c 没有值,而预处理器表达式在构建时被评估(事实上,正如名称所示,在编译器处理代码之前),因此只能操作在构建时存在的预处理器符号。
此外,这样的表达式必须是编译时常量,或者更确切地说是预处理时间常量,因为编译器常量表达式(例如sizeof(...))也没有在预处理期间定义。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接