鉴于以下C文件:
$ cat macros.c
#ifdef MACRO
# error MACRO is defined
#else
# error MACRO is undefined
#endif
#if MACRO
# error MACRO is non-zero
#else
# error MACRO is zero
#endif
以下内容的预期输出是什么?
$ gcc -c macros.c
$ gcc -DMACRO -c macros.c
$ gcc -DMACRO=0 -c macros.c
回答:这是我机器上gcc的预处理程序。
$ gcc -c macros.c
macros.c:4:4: error: #error MACRO is undefined
macros.c:9:4: error: #error MACRO is zero
$ gcc -DMACRO -c macros.c
macros.c:2:4: error: #error MACRO is defined
macros.c:7:4: error: #error MACRO is non-zero
$ gcc -DMACRO=0 -c macros.c
macros.c:2:4: error: #error MACRO is defined
macros.c:9:4: error: #error MACRO is zero
$
课程:#ifdef MACRO
对于定义的评估为true,即使定义的值为0(零)。
另一个C预处理器了!根据C标准,它应该如何?
答案 0 :(得分:7)
为了评估#if
语句的控制表达式,任何未定义的宏都被视为0。从C99§6.10.1/ 3-4(重点补充):
3)表格的预处理指令
# if constant-expression new-line group
<子>opt
子>
# elif constant-expression new-line group
opt
检查控制常量表达式是否计算为非零值。
4)在评估之前,将在预处理令牌列表中进行宏调用 控制常量表达式被替换(除了那些修改过的宏名称) 由
defined
一元运算符),就像在普通文本中一样。如果令牌defined
是 由于此替换过程或使用defined
一元运算符而生成的 在宏替换之前,它与两个指定表单中的一个不匹配,行为是 未定义。 由于宏扩展和defined
一元而导致的所有替换后 运算符已执行,所有剩余的标识符(包括那些词法 与关键字相同)被替换为pp-number 0 ,然后进行每次预处理 令牌转换为令牌。 [...]
所以,例如,像这样的表达式:
#if !FOO
如果1
未定义,则评估为FOO
,因为它将被视为0,然后!FOO
将被评估为!0
,即1
1}}。
答案 1 :(得分:5)
#ifdef
只关心MACRO是否已被定义。价值无关紧要。
#if
检查MACRO的值并相应地评估MACRO。
这是正确的行为
答案 2 :(得分:2)
行为符合标准。
C99标准:6.10.1条件包含:
第2段:表格的预处理指令
# if constant-expression new-line groupopt
# elif constant-expression new-line groupopt
检查控制常量表达式是否计算为非零值。
第4段:表格的预处理指令
# ifdef identifier new-line groupopt
# ifndef identifier new-line groupopt
检查标识符当前是否定义为宏名称。其
条件等同于#if defined
标识符和#if !defined
标识符
分别