几乎任何 C 预处理器,包括 gcccpp
,将假设其输入是有效的 C 代码。它必须按照 C(或 C++、或 Objective-C)规则对输入进行标记,因为它必须将其输入解析为标记(更准确地说是预处理标记)。令牌级别之上的构造不应成为问题。
你当然可以使用cpp
or gcc -E
预处理不是 C 源代码的文本,但某些输入结构会导致问题。
举个评论里的例子:
$ cat foo.txt
#define ADDTHEM(x, y) ((x) + (y))
ADDTHEM(2, 3)
$ gcc -E - < foo.txt
# 1 "<stdin>"
# 1 "<command-line>"
# 1 "<stdin>"
((2) + (3))
请注意,我必须使用gcc -E - < foo.txt
而不是gcc -E foo.txt
,因为 gcc 对待.txt
文件默认作为链接器输入文件。
但如果你添加一些内容foo.txt
不包含有效的 C 预处理器标记,您可能会遇到问题:
$ cat foo.txt
#define ADDTHEM(x, y) ((x) + (y))
ADDTHEM(2, 3)
ADDTHEM('c, "s)
$ gcc -E - < foo.txt
# 1 "<stdin>"
# 1 "<command-line>"
# 1 "<stdin>"
((2) + (3))
<stdin>:3:9: warning: missing terminating ' character [enabled by default]
<stdin>:3:0: error: unterminated argument list invoking macro "ADDTHEM"
ADDTHEM
(尝试将 Ada 源代码提供给 C 预处理器会遇到此类问题,因为 Ada 使用独立的撇号'
其属性语法的字符。)
所以你可以做到if输入语言不使用无效的 C 预处理器标记。
See N1570草案有关预处理标记的更多信息,请参见 C 标准第 6.4 节。
我实际上在检查之前写了上面的内容GNU cpp 手册,其中说:
C 预处理器仅适用于 C、C++ 和
Objective-C 源代码。过去曾被滥用为将军
文本处理器。它会因为不遵守 C 词法的输入而卡住
规则。例如,撇号将被解释为
字符常量,并导致错误。另外,你不能依赖它
保留对输入不重要的特征
C 族语言。如果一个 Makefile 被预处理,所有的硬选项卡
将被删除,并且 Makefile 将不起作用。
话虽如此,您通常可以在事物上使用 cpp
不是 C。其他类似 Algol 的编程语言通常是安全的
(Pascal、Ada 等)汇编也是如此,请谨慎使用。 `-传统-cpp'
模式保留更多空白,并且在其他方面更宽松。许多
的问题可以通过编写 C 或 C++ 风格的注释来避免
而不是本地语言注释,并保持宏简单。
只要有可能,您应该使用适合的预处理器
您正在编写的语言。现代版本的 GNU 汇编器有
宏观设施。大多数高级编程语言都有自己的
条件编译和包含机制。如果一切都失败了
尝试真正的通用文本处理器,例如 GNU M4。
(该手册的作者显然忽略了 Ada 属性语法的问题。)