如果条件指令中使用的任何非宏变量的计算结果为0,是否正确?

时间:2014-03-01 18:39:43

标签: c macros c-preprocessor preprocessor-directive

我们说我有以下代码。根据 C 规范,条件指令始终评估为零是正确的,因为M在编译时间之前展开,i的值为zero ?如果我错了,有人可以解释一下:

#include <stdio.h>

#define M i

int main() {
    int i = 10;
    #if M == 0
     i = 0;
    #endif
    printf("%d", i);
    return 0;
}

2 个答案:

答案 0 :(得分:4)

使用#if非宏的标识符都被视为数字zerogcc docs for #if列出了要求nicel,它说(强调我的前进):

#if expression
  

表达式是整数类型的C表达式,受到严格的限制。它可能包含

  • 整数常量。
  • 字符常量,解释为普通代码。
  • 用于加法,减法,乘法,除法,按位运算,移位,比较和逻辑运算(&amp;&amp;和||)的算术运算符。后两者遵守标准C的通常短路规则。
  • 宏。在实际计算表达式的值之前,表达式中的所有宏都会被扩展。
  • 使用已定义的运算符,可以检查是否在'#if'中间定义了宏。
  • 不是宏的标识符,它们都被认为是数字零。如果你知道定义的MACRO,你可以写#if MACRO而不是#ifdef MACRO始终具有非零值。没有函数调用括号的函数式宏也被视为零。

并注意到:

  

在某些情况下,这种捷径是不可取的。 -Wundef选项会导致GCC在遇到不是'#if'中的宏的标识符时发出警告。

draft C99 standard部分6.10.1 条件包含 4 中包含以下内容:

  

[...]由于宏扩展和定义的一元所有替换后   运算符已执行,所有剩余标识符(包括那些词法   与关键字相同)被替换为pp-number 0 ,然后进行每次预处理   令牌被转换为令牌。[...]

答案 1 :(得分:1)

是的,它们被视为数字0。

  

C11§6.10.1条件包含

     

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

pp-number 在这里引用§6.4.8中的预处理数