abu*_*ker 7 stringification c-preprocessor
我想用预处理器评论一行:
#define open /##*
#define close */
main()
{
open commented line close
}
Run Code Online (Sandbox Code Playgroud)
当我做$gcc -E filename.c我想到的
/* commented line */
Run Code Online (Sandbox Code Playgroud)
但我明白了
/ * commented line */
Run Code Online (Sandbox Code Playgroud)
这样编译器就会显示错误
为什么会给出不必要的空间?
从GNU C预处理器文档:
但是,不能一起形成有效令牌的两个令牌不能粘贴在一起.例如,您无法以任何顺序将x与+连接.如果您尝试,预处理器会发出警告并发出两个令牌.是否在令牌之间放置空格是不确定的.在复杂的宏中发现'##'的不必要用法是很常见的.如果您收到此警告,则可能只需删除"##"即可.
在这种情况下,'*'和'/'不会形成有效的C或C++令牌.因此它们在它们之间留有空间.
(旁白:即使你设法将"注释"插入到C预处理器的输出中,你也可能会得到C编译错误.那里不应该有任何注释.)
该错误是因为/*不是有效的令牌.
正如CPP文件所解释的那样:
不能一起形成有效令牌的两个令牌不能粘贴在一起.例如,您无法
x以+任何顺序连接.
您可以通过粘贴其他无意义的东西来获取错误,例如/##+或+##-.
关于空间,它是故意插入,以避免创建评论和搞乱其余部分.来自GCC源代码:
/* 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++ = ' ';
Run Code Online (Sandbox Code Playgroud)
预处理器以 C 编译器可以理解的形式运行并生成代码。它只处理您的代码一次,因此即使您可以/*使用生成 a #define,编译器也会看到/*并给您一个错误,因为它不是有效的 C 代码(它是预处理指令)。
这似乎不是一件好事。