据我所知{C}中的\
只是附加下一行,好像没有换行符。
请考虑以下代码:
main(){\
return 0;
}
当我看到预处理代码(gcc -E
)时,它会显示
main(){return
0;
}
而不是
main(){return 0;
}
这种行为的原因是什么?另外,我如何获得我期望的代码?
答案 0 :(得分:10)
来自K&R section A.12 Preprocessing:
A.12.2线拼接
以反斜杠字符\结尾的行 通过删除反斜杠和以下换行符折叠。 这在分成令牌之前发生。
答案 1 :(得分:10)
是的,您的预期结果是C和C ++标准所要求的结果。反斜杠只是转义换行符,即删除反斜杠换行符序列。
我的OS X安装中的GCC 4.2.1给出了预期的结果,Clang也是如此。此外,在开头添加#define
并使用
#define main(){\
return 0;
}
main()
产生正确的结果
}
{return 0;
也许gcc -E
在预处理之后和输出之前做了一些额外的处理。在任何情况下,预处理器其余部分看到的换行似乎都在正确的位置。所以这是一个美容虫。
更新:根据GCC FAQ,-E
(或cpp
命令的默认设置)尝试将输出令牌置于大致相同的视觉效果中作为输入令牌的位置。要获得“原始”输出,请同时指定-P
。这解决了观察到的问题。
可能发生了什么:
{
和return
令牌被分组到同一个视觉块中。0
跟随一个空格,并在下一行的位置被正确记录。PLUG:如果这对您来说非常重要,我已经实现了my own preprocessor,正确实现了原始预处理和保留空白的“漂亮”模式。在讨论之后,我added将拼接线连接到保留的空白。但是,它并不是真正的独立工具。它是编译器框架的测试平台,恰好是一个完全兼容的C ++ 11预处理器库,恰好有一个微型命令行驱动程序。 (但错误信息与GCC相同,或者Clang,没有颜色。)
答案 2 :(得分:4)
无所谓:/令牌化器不会看到任何差异。 1
更新回复评论:
对于预处理器的预期输出应该是多少,似乎存在相当大的混淆。我的观点是期望/似乎/合理一目了然但实际上并不需要以这种方式指定输出有效。输出中存在的空白量与解析器无关。重要的是预处理器应该在解释它时将续行视为一行。
换句话说:预处理器不是文本转换工具,它是一种令牌操作工具。
如果对你很重要,你可能
1 (预处理器可以按照它认为合适的方式自由地实现指定的结果。您看到的结果可能是实现者实现此特定转换的最有效方式)< / p>