下面是一个相关示例。这显然是无效的C,但我只是在这里处理预处理器,所以代码实际上并不需要编译。在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的编译器不应该在宏扩展期间插入额外的空格,因为它可能会防止编程错误。
+1。我认为关键的见解是,-E的输出确实没有被标准规定。该标准讨论了由一系列预处理令牌组成的程序,然后将其转换为令牌序列。这完全取决于预处理器如何表示这些序列,并且在这种情况下如何将它们序列化为一个* bytes *序列的文件。当然,唯一可行的序列化是可以作为等价的一系列预处理令牌读回来的,所以,如你所说,它必须在两个令牌之间放置空白,这两个令牌形成一个。 – 2010-11-12 14:14:36
我同意100%,想写一些像你的解释,但没有时间。 – 2010-11-12 15:28:55
好的答案,虽然我有两个nitpicky的评论:没有'''* *'标记的东西;在标记之前,注释会从源中删除。你可以使用'##'从两个'+'令牌形成'++'标记。 – 2010-11-12 16:40:47