对于定义为0的宏,#ifdef和#if之间的细微差别

给出下面的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即使定义的值为0(零),MACRO也会对定义的内容求值为true.

一个C预处理器了!这是按照C标准应该如何吗?

解决方法

为了评估#if语句的控制表达式,任何未定义的宏都被视为0.从C99§6.10.1/ 3-4(重点补充):

3) Preprocessing directives of the forms

# if constant-expression new-line groupopt
# elif constant-expression new-line groupopt

check whether the controlling constant expression evaluates to nonzero.

4) Prior to evaluation,macro invocations in the list of preprocessing tokens that will become
the controlling constant expression are replaced (except for those macro names modified
by the defined unary operator),just as in normal text. If the token defined is
generated as a result of this replacement process or use of the defined unary operator
does not match one of the two specified forms prior to macro replacement,the behavior is
undefined. After all replacements due to macro expansion and the defined unary
operator have been performed,all remaining identifiers (including those lexically
identical to keywords) are replaced with the pp-number 0
,and then each preprocessing
token is converted into a token. […]

所以,例如,像这样的表达式:

#if !FOO

如果FOO未定义,将评估为1,因为它将被视为0,然后!FOO将被评估为!0,即1.

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...