我想使用预处理器评论一行:
#define open /##*
#define close */
main()
{
open commented line close
}
当我做$gcc -E filename.c
我期待
/* commented line */
但我得到了
/ * commented line */
以便编译器显示错误
为什么会给出不必要的空间?
答案 0 :(得分:6)
来自GNU C预处理器文档:
但是,两个不能一起形成有效令牌的令牌无法粘贴在一起。例如,您无法以任何顺序将x与+连接。如果您尝试,预处理器会发出警告并发出两个令牌。是否在令牌之间放置空格是不确定的。在复杂的宏中发现'##'的不必要用法是很常见的。如果您收到此警告,则可能只需删除“##”即可。
在这种情况下,'*'和'/'不会形成有效的C或C ++令牌。因此,它们之间会有一个空间。
(旁白:即使您设法将“注释”插入C预处理器的输出中,您也可能会遇到C编译错误。那里不应该有任何注释。)
答案 1 :(得分:5)
错误是因为/*
不是有效令牌。
正如CPP doc:
所述不能一起形成有效令牌的两个令牌不能粘贴在一起。例如,您无法以任何顺序将
x
与+
连接起来。
您可以通过粘贴其他无意义的内容来获取错误,例如/##+
或+##-
。
关于空间,故意插入以避免创建评论并弄乱其余部分。来自GCC source code:
/* Avoid comment headers, since they are still processed in stage 3.
It is simpler to insert a space here, rather than modifying the
lexer to ignore comments in some circumstances. Simply returning
false doesn't work, since we want to clear the PASTE_LEFT flag. */
if ((*plhs)->type == CPP_DIV && rhs->type != CPP_EQ)
*end++ = ' ';
答案 2 :(得分:3)
预处理器以C编译器可以理解的形式运行并生成代码。它只处理你的代码一次,所以即使你可能用你的/*
产生#define
,编译器也会看到/*
并给你一个错误,因为它不是有效的C代码(它是一个预处理指令)。
这似乎不是一件好事。
答案 3 :(得分:3)
因为在预处理器运行之前(且仅在之前),注释被替换为空格。如果您使用预处理器将字符/
和*
粘贴在一起,则会得到/*
,这只是几个运算符。 编辑:此类滥用##
在技术上会将/*
创建为单个令牌,具有未定义的行为。您可以将> ## >
或< %:%: :
粘贴在一起,但不应该。
参见C99的§6.4.6,了解允许构建的令牌和6.10.3.3的连接过程。
答案 4 :(得分:0)
如果您想使用预处理器评论某些代码,请使用
#if 0
...
#endif