几乎任何 C 预处理器,包括 gcc 的cpp
,都会假设其输入是有效的 C 代码。它必须按照 C(或 C++,或 Objective-C)规则对输入进行标记,因为它必须将其输入解析为标记(更准确地说是预处理标记)。高于令牌级别的构造不应该成为问题。
您当然可以使用cpp
或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 使用孤立的撇号'
字符作为其属性语法。)
因此,如果输入语言不使用不是有效的 C 预处理器标记的东西,您可以这样做。
有关预处理令牌的更多信息,请参阅C 标准的 N1570 草案第 6.4 节。
在我检查GNU cpp 手册之前,我实际上写了上面的内容,上面写着:
C 预处理器仅适用于 C、C++ 和 Objective-C 源代码。过去,它被滥用为通用文本处理器。它将阻塞不遵守 C 的词法规则的输入。例如,撇号将被解释为字符常量的开头,并导致错误。此外,您不能依赖它保留对 C 系列语言不重要的输入特征。如果对 Makefile 进行了预处理,则所有硬标签都将被删除,并且 Makefile 将无法工作。
话虽如此,您通常可以在非 C 的东西上使用 cpp。其他类似 Algol 的编程语言通常是安全的(Pascal、Ada 等)。汇编也是如此,请谨慎行事。`-traditional-cpp' 模式保留更多的空白,否则更宽松。通过编写 C 或 C++ 样式的注释而不是本地语言注释并保持宏简单,可以避免许多问题。
只要有可能,您应该使用适合您编写的语言的预处理器。现代版本的 GNU 汇编器具有宏工具。大多数高级编程语言都有自己的条件编译和包含机制。如果一切都失败了,请尝试真正的通用文本处理器,例如 GNU M4。
(该手册的作者显然忽略了 Ada 属性语法的问题。)