+-
用C中的#define正确放置事物还是在其前后留空格?

据我所知,在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

从输出的第二行很明显,不会进行增量和减量。

这意味着在替换kkk之后,它变为:

t = (35*xx+ +-6+- -x*2)*4;

((如果是,则计算是清楚的。)

我的关注点:是C的标准还是只是未定义的行为?还是我做错了?

0
投票

C标准指定对源文件进行分析并将其解析为预处理器令牌。发生宏替换时,将替换的宏替换为这些标记。替换不是文字文本替换。

C 2018 5.1.1.2指定了翻译阶段(措辞和摘要,不完全是引号):

物理源文件多字节字符被映射到源字符集。 Trigraph序列由单字符表示形式代替。

反斜线继续合并。

源文件从字符转换为预处理标记和空白字符-可以作为预处理标记的每个字符序列都转换为预处理标记,并且每个注释变为一个空格。

执行预处理(执行指令并扩展宏)。

将字符常量和字符串文字中的源字符转换为执行字符集的成员。

相邻字符串文字是串联的。

空格字符将被丢弃。 “每个预处理令牌都转换为令牌。生成的令牌将在语法和语义上进行分析,并作为翻译单元进行翻译。” (引用的文本是我们认为的C编译的主要部分!)

程序已链接为可执行文件。