+-
据我所知,在C中,C预处理程序替换了#define
中的文字。但是现在,我看到了,它在前后都有空格。
我的解释正确吗,或者我正在做一些应该给出不确定行为的动作?
请考虑以下C代码:
#include <stdio.h>
#define k +-6+-
#define kk xx+k-x
int main()
{
int x = 1029, xx = 4,t;
printf("x=%d,xx=%d\n",x,xx);
t=(35*kk*2)*4;
printf("t=%d,x=%d,xx=%d\n",t,x,xx);
return 0;
}
初始值是:x = 1029,xx = 4。现在计算t的值。
t = (35*kk*2)*4;
t = (35*xx+k-x*2)*4; // replacing the literal kk
t = (35*xx++-6+--x*2)*4; // replacing the literal k
现在,xx = 4的值将在下一条语句中增加1,而x的值将减1并成为1028。因此,当前语句的计算:
t = (35*4-6+1028*2)*4;
t = (140-6+2056)*4;
t = 2190*4;
t = 8760;
但是上面代码的输出是:
x=1029,xx=4
t=8768,x=1029,xx=4
从输出的第二行很明显,不会进行增量和减量。
这意味着在替换k和kk之后,它变为:
t = (35*xx+ +-6+- -x*2)*4;
((如果是,则计算是清楚的。)
我的关注点:是C的标准还是只是未定义的行为?还是我做错了?
0
投票
投票
C标准指定对源文件进行分析并将其解析为预处理器令牌。发生宏替换时,将替换的宏替换为这些标记。替换不是文字文本替换。
C 2018 5.1.1.2指定了翻译阶段(措辞和摘要,不完全是引号):
物理源文件多字节字符被映射到源字符集。 Trigraph序列由单字符表示形式代替。
反斜线继续合并。
源文件从字符转换为预处理标记和空白字符-可以作为预处理标记的每个字符序列都转换为预处理标记,并且每个注释变为一个空格。
执行预处理(执行指令并扩展宏)。
将字符常量和字符串文字中的源字符转换为执行字符集的成员。
相邻字符串文字是串联的。
空格字符将被丢弃。 “每个预处理令牌都转换为令牌。生成的令牌将在语法和语义上进行分析,并作为翻译单元进行翻译。” (引用的文本是我们认为的C编译的主要部分!)
程序已链接为可执行文件。