为什么C/C++预处理器在这里添加了一个空格

Why is C/C++ preprocessor adding a space here?

本文关键字:空格 一个 添加 C++ 预处理 在这里 处理器 为什么      更新时间:2023-10-16

我的预处理器有一个小问题,困扰着我,在文档/预处理器/语言规范中找不到任何解释。

#define booboo() aaa
booboo()bbb
booboo().bbb

被预处理为:

aaa bbb   <--- why is space added here
aaa.bbb

在处理了触发器、连续行和注释之后,预处理器处理预处理器指令,并将输入划分为预处理标记和空白。booboo的替换列表包括一个pp令牌,该令牌是标识符"aaa"。booboo()bbb分为pp令牌:"booboo"、"("、")"、"bbb"。"booboo"、"("、")"的序列被识别为函数宏调用,它应该扩展为"aaa",输出中的imho应该看起来像"aaabbb"。我说看起来像是因为对人类来说,它看起来像是一个令牌,而编译器会得到两个令牌"aaa"answers"bbb",因为没有使用允许pp令牌串联的"##"运算符。当"booboo().bbb"导致"aaa.bbb"没有空格时,为什么/什么规则使cpp(c预处理器)在"aaa"answers"bbb"之间放置额外的空格?

这是因为cpp试图使输出(主要是针对人类的)不明确吗?人类无法判断"aaabbb"是由两个令牌组成的,因为它只看到令牌的拼写。我说得对吗?我已经阅读了关于预处理器的C99文档和gcc的cpp文档。我对此一无所知。

如果我是对的,我们这里也有类似的情况:

#define baba() +
baba()+
baba()-

结果在:

+ +
+-

否则(如果"++"是输出),它将看起来像一个类似人类的"++"标记,但会有两个标记"+"answers"+"。与"##"运算符类似,cpp检查连接是否产生有效的令牌,但在所示的情况下,它希望阻止执行连接的人为操作吗?"+-"没有歧义,因此没有添加空间

预处理的结果是将源文件转换为令牌列表。在您的情况下,令牌列表在令牌化后会是这样的:

....
booboo()
bbb
....

然后在宏替换后:

....
aaa
bbb
....

然后编译器将标记列表转换为可执行文件。

您看到的空白只是编译器等在向您显示中间结果时选择的用于布置预处理标记的实现细节。这些标准没有提及任何中间处理文件。也不需要有单独的程序来进行预处理。

我在90年代初自己写了一个ANSI C编译器。据我记忆所及,一个评论标记//应替换为单个空白。宏就地执行文本替换。这种宏扩展的文本替换所产生的令牌不一定是合法的C语言令牌。当宏被定义为文本"aaa"时,它只是进入输入流的文本"aaa"。因此,C的解析器可能会也可能不会看到有效的令牌!

因此,给定:

定义booboo()aaa

展开booboo()bbb应产生文本aaabbb

这个aaabbb是什么意思取决于用户。但是,即使aaabbb恰好是宏的名称,也不会对其进行预处理。这是肯定的。但是aaabbb可以是一个用户标识符——没有问题。

相关文章: