vap*_*ace 6 c macros c-preprocessor
给出下面的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
Run Code Online (Sandbox Code Playgroud)
以下的预期产量是多少?
$ gcc -c macros.c
$ gcc -DMACRO -c macros.c
$ gcc -DMACRO=0 -c macros.c
Run Code Online (Sandbox Code Playgroud)
答:这是我机器上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
$
Run Code Online (Sandbox Code Playgroud)
课程:即使定义的值为0(零),也会#ifdef MACRO对定义的内容求值为true .
另一个C预处理器了!这是按照C标准应该如何吗?
为了评估#if语句的控制表达式,任何未定义的宏都被视为定义为0 .从C99§6.10.1/ 3-4(重点补充):
3)表格的预处理指令
# if constant-expression new-line groupopt
# elif constant-expression new-line groupopt检查控制常量表达式是否计算为非零.
4)在评估之前,将替换将成为控制常量表达式的预处理标记列表中的宏调用(除了由
defined一元运算符修改的那些宏名称之外),就像在普通文本中一样.如果defined由于此替换过程而生成令牌,或者defined在宏替换之前使用一元运算符与两个指定表单中的一个不匹配,则行为是未定义的.在由于宏扩展和defined一元运算符执行的所有替换之后,所有剩余的标识符(包括与关键字词法相同的标识符)被替换为pp-number 0,然后每个预处理标记被转换为标记.[...]
所以,例如,像这样的表达式:
#if !FOO
Run Code Online (Sandbox Code Playgroud)
将评估1if FOO是否未定义,因为它将被视为0,然后!FOO将被评估为!0,即1.
小智 5
#ifdef 只关注MACRO是否已被定义.价值无关紧要.
#if 检查MACRO的值并相应地评估MACRO.
这是正确的行为
行为符合标准。
C99标准: 6.10.1 有条件包含:
第 2 段:表单的预处理指令
# if constant-expression new-line groupopt
# elif constant-expression new-line groupopt
Run Code Online (Sandbox Code Playgroud)
检查控制常量表达式的计算结果是否为非零。
第 4 段:表单的预处理指令
# ifdef identifier new-line groupopt
# ifndef identifier new-line groupopt
Run Code Online (Sandbox Code Playgroud)
检查标识符当前是否定义为宏名称。它们的条件分别相当于#if defined 标识符和#if !defined 标识符
。
| 归档时间: |
|
| 查看次数: |
6471 次 |
| 最近记录: |