该程序将输出设为5.但是在替换所有宏之后,它将导致--5.这应该导致编译错误,试图减少5.但它编译并运行良好.
#include <stdio.h>
#define A -B
#define B -C
#define C 5
int main()
{
printf("The value of A is %d\n", A);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
为什么没有错误?
以下是编译语句的步骤printf("The value of A is %d\n", A);:
printf,(,"The value of A is %dn",,,A,)和;.A为展开至所述2个令牌的宏-和B.B也是一个宏,并扩展到-和C.C又是一个宏,并扩展到5.0a).在此示例中,令牌是相同的.printf,(,"The value of A is %d\n",,,-,-,5,),;匹配的函数调用printf以2个参数:一个格式字符串和一个常量表达式- - 5,其计算结果为5在编译时.因此代码相当于printf("The value of A is %d\n", 5);.它会产生输出:
The value of A is 5
Run Code Online (Sandbox Code Playgroud)这个宏序列扩展为标记,而不是严格的字符序列,因此A不会扩展为--5,而是扩展为- -5.好的C编译器在将源预处理到文本输出时会插入额外的空间,以确保生成的文本在重新分析时产生相同的标记序列.但请注意,C标准没有说明文本输出的预处理,它只指定预处理作为解析阶段之一,并且编译器在预处理到文本输出时不会引入潜在的副作用,这是一个实现质量问题.
有一个单独的功能可以将令牌组合到预处理器中称为令牌粘贴的新令牌中.它需要一个特定的操作员##,使用起来非常棘手.
另请注意,应在每个参数周围使用括号定义宏,并在整个扩展周围使用括号以防止运算符优先级问题:
#define A (-B)
#define B (-C)
#define C 5
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
98 次 |
| 最近记录: |