gpt4 book ai didi

c - 在 C 宏扩展期间,是否存在扩展为 "/*"的宏的特殊情况?

转载 作者:太空狗 更新时间:2023-10-29 16:38:02 24 4
gpt4 key购买 nike

这是一个相关的例子。它显然不是有效的 C,但我只是在这里处理预处理器,所以代码实际上不必编译。

#define IDENTITY(x) x
#define PREPEND_ASTERISK(x) *x
#define PREPEND_SLASH(x) /x

IDENTITY(literal)
PREPEND_ASTERISK(literal)
PREPEND_SLASH(literal)
IDENTITY(*pointer)
PREPEND_ASTERISK(*pointer)
PREPEND_SLASH(*pointer)

在其上运行 gcc 的预处理器:

gcc -std=c99 -E macrotest.c

这会产生:

(...)

literal
*literal
/literal
*pointer
**pointer
/ *pointer

请注意最后一行的额外空格。

对我来说,这看起来像是一个防止宏扩展为“/*”的功能,我确信这是出于好意。但乍一看,我在 C99 标准中找不到任何与此行为有关的内容。再一次,我在 C 方面缺乏经验。有人可以阐明这一点吗?这是在哪里指定的?我猜想遵循 C99 的编译器不应该只是在宏扩展期间插入额外的空格,因为它可能会防止编程错误。

最佳答案

源代码在被 CPP 处理之前已经被标记化。

所以你拥有的是一个 / 和一个 * token ,它们不会隐式组合成一个 /* “ token ”(因为/* 不是真正的预处理器标记,我把它放在 "") 中。

如果您使用 -E 输出预处理后的源代码,CPP 需要插入一个空格以避免 /* 被后续编译器读取。

相同的功能可以防止两个,例如来自不同宏的 + 符号在输出时组合成一个 ++ 标记。

真正将两个预处理器标记粘贴在一起的唯一方法是使用 ## 运算符:

#define P(x,y) x##y

...

P(foo,bar)

生成 token foobar

P(+,+)

生成 token ++,但是

P(/,*)       

无效,因为 /* 不是有效的预处理器标记。

关于c - 在 C 宏扩展期间,是否存在扩展为 "/*"的宏的特殊情况?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4165278/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com