在C条件编译#if和#else指令(和其他人)的工作

时间:2019-02-02 18:31:56

标签: c c-preprocessor preprocessor conditional-compilation preprocessor-directive

我试图使用一些条件编译预处理指令而不是“ if-else”编写程序,如下所示。

#include<stdio.h>
int main ()
{
    int x;
    scanf ("%d",&x);
#if (x==5)
    printf ("x is 5");
#else
    printf ("x not 5");
#endif
}

但事实是,即使x的值为5,它也始终打印else部分。我最简单的问题是-----> 为什么?

是否有可能成功地完成本程序(即使用的#if下#if指令和打印语句采取从用户和检查条件x的值)。

在编译期间它示出了警告的 “的 'x' 没有定义,计算结果为0” 即可。但是x在我看来似乎已经定义了。这是否意味着x应该用定义#define。请给我解释一下概念背后条件编译。

4 个答案:

答案 0 :(得分:3)

x是不是一个整数字面或一个整数文字表达(整数常量+运营商)或扩展到那些宏,因此在条件,预处理器替换它与0({{3 }})。 0==5是假的,所以#else分支被采用。

预处理器不了解C声明,类型等。它仅适用于标记(和宏最终扩展到那些)。


6.10.1p4

  

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

答案 1 :(得分:1)

预处理在编译之前进行。因此,预处理器对您的C代码或变量一无所知。您不能在条件中使用任何C变量。

条件编译为不同的目的。

#define DEBUG

/* ....*/ 

#ifdef DEBUG 
printf("Some debug value %d\n", val);
#endif

答案 2 :(得分:0)

#if语句中的操作数只能是常量,用#define定义的事物和特殊的defined运算符。表达式中的所有其他标识符均替换为0。示例代码中的x未使用#define定义,因此(x==5)变为(0==0)

在C 2018标准中,第6.10.1节告诉我们,在#if语句中对表达式的求值包括:

  • 预处理器宏(用#define定义的内容)将根据其定义进行替换。
  • defined运算符的使用替换为0或1。
  • 所有剩余的标识符都将替换为0。

由于示例代码中的x未使用#define定义,因此在#if语句中将其替换为0。这将导致(0==5)的错误,因此将跳过#if#else之间的代码。

在预处理程序语句中,您不能基于将在程序执行期间设置的值来评估变量。

答案 3 :(得分:-2)

这是“预处理器”。 “前”, “预” 的意思。

您正在尝试使用的运行的预处理过程中的价值!当然,预处理器在构建期间无法访问该信息。

此问题不限于运行时的值,但是更基本的。即使你试图使用一个(命名)编译时间常数,例如constexpr int x = 2,你不能这样做。这是两种语言交织,就像PHP生成HTML;在HTML没有PHP变量的知识,和PHP没有什么部件在页面上的用户点击知识。这些是完全不同的执行上下文与没有内置的相互作用或交叉兼容性。