#define应该在宏周围添加空格吗?

Dav*_*d Z 3 c macros whitespace gcc c-preprocessor

我正在查看http://www0.us.ioccc.org/1988/westley.c上的程序,在另一个SO答案中提到- 它应该打印pi的值,大约3.142,但是当我编译它并运行时我得到它0.250.看起来当GCC预处理器(经过测试的4.1.2和3.4.6)在代码上运行时,它会转换

#define _ -F<00||--F-OO--;
_-_-_
Run Code Online (Sandbox Code Playgroud)

-F<00||--F-OO--;- -F<00||--F-OO--;- -F<00||--F-OO--;
Run Code Online (Sandbox Code Playgroud)

但我认为,要使该计划有效,它应该是

-F<00||--F-OO--;--F<00||--F-OO--;--F<00||--F-OO--;
Run Code Online (Sandbox Code Playgroud)

即GCC在"宏观"扩张之前插入一个额外的空间.这#define是应该的方式吗?(自1988年以来有变化吗?)

编辑:此外,任何有关如何防止这些空间出现的信息将不胜感激.

Ada*_*eld 11

只有很多较旧的预处理器没有插入额外的空间 - 请注意原始条目是在20年前的1988年提交的,而1989年版本的C标准已经标准化.您可以将-traditional-cpp标志传递给GCC预处理器,这会导致它模仿旧式C预处理器的行为,而不是ISO C预处理器.


Gre*_*ers 6

预处理器对令牌进行操作,而不是严格的文本.所以从技术上来说,它并没有"间隔",但除非你明确告诉它将两个令牌与##操作员粘贴在一起,否则它不会这样做.在这种情况下,两个-跨越宏的行被计为两个不同的标记 - 都意味着一元减去,而不是减少.

另见:http://en.wikipedia.org/wiki/C_preprocessor#Token_concatenation


Mic*_*urr 5

从C99标准:

表单的预处理指令

#define identifier replacement-list new-line

定义一个类似于对象的宏,它使宏名称的每个后续实例都被构成指令其余部分的预处理标记的替换列表替换.

因此宏可以处理令牌,并且可以预期空白.

并且您可以使用令牌粘贴运算符获得所需的输出##,但是您需要使用一些进一步的宏难度来执行此操作:

#define PASTE2( x, y) x##y
#define PASTE( x, y) PASTE2(x, y)

#define _ -F<00||--F-OO--;


PASTE(PASTE(PASTE(PASTE(_,-),_),-),_)
Run Code Online (Sandbox Code Playgroud)

所以我不确定这对你来说是一个真正的答案.

您可以使用一组不那么丑陋的宏来获取所需的表达式 - 仍然会有一些空格,但这些空格不会干扰创建' --'运算符:

_ PASTE(-,_) PASTE(-,_)
Run Code Online (Sandbox Code Playgroud)

不过,我仍然怀疑这是你想要的.