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