cur*_*mer 13 c macros c99 c-preprocessor
这是一个相关的例子.它显然不是有效的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)
Run Code Online (Sandbox Code Playgroud)
在其上运行gcc的预处理器:
gcc -std=c99 -E macrotest.c
Run Code Online (Sandbox Code Playgroud)
这会产生:
(...)
literal
*literal
/literal
*pointer
**pointer
/ *pointer
Run Code Online (Sandbox Code Playgroud)
请注意最后一行的额外空间.
这看起来像一个功能,以防止宏扩展到"/*"给我,我敢肯定是善意的.但是一目了然,我在C99标准中找不到任何与此行为有关的内容.然后,我对C缺乏经验.有人可以对此有所了解吗?这指定在哪里?我猜想一个坚持C99的编译器不应该只是在宏扩展期间插入额外的空格,因为它可能会阻止编程错误.
Pee*_*ger 15
源代码在被CPP处理之前已经被标记化.
所以你拥有的是一个/和一个*不会隐式组合成/*"令牌"的令牌(因为/*实际上并不是我把它放在""中的预处理器令牌).
如果使用-E输出预处理源CPP,则需要插入空格以避免/*被后续编译器传递读取.
相同的特征防止来自+不同宏的两个例如符号++在输出上被组合成令牌.
将两个预处理程序标记粘贴在一起的唯一方法是使用##运算符:
#define P(x,y) x##y
...
P(foo,bar)
Run Code Online (Sandbox Code Playgroud)
导致令牌 foobar
P(+,+)
Run Code Online (Sandbox Code Playgroud)
导致令牌++,但是
P(/,*)
Run Code Online (Sandbox Code Playgroud)
无效,因为/*它不是有效的预处理程序令牌.
预处理器的行为是标准化的.在http://en.wikipedia.org/wiki/C_preprocessor的摘要中,您观察到的结果是:
"3:标记化 - 预处理器将结果分解为预处理标记和空格.它用空格替换注释".
这发生在:
"4:宏观扩张和指令处理".
| 归档时间: |
|
| 查看次数: |
889 次 |
| 最近记录: |