对 C 以外的语言使用 C 预处理器
C 预处理器 的 Wikipedia 条目指出:
预处理器的语言 指令与语法无关 C,因此 C 预处理器还可以 独立使用来处理其他 文件类型。
如何才能做到这一点? 有什么例子或技巧吗?
编辑:是的,我最感兴趣的是宏处理。 尽管它可能不可取或不可维护,但了解可能的情况仍然很有用。
The Wikipedia entry for the C Preprocessor states:
The language of preprocessor
directives is agnostic to the grammar
of C, so the C preprocessor can also
be used independently to process other
types of files.
How can this be done? Any examples or techniques?
EDIT: Yes, I'm mostly interested in macro processing. Even though it's probably not advisable or maintainable it would still be useful to know what's possible.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(12)
不久前,我在一个使用
imake
生成 makefile 的项目上做了一些工作。 我记得,它基本上是使用 c 预处理器语法来生成 make 文件的。A while ago I did some work on a project that used
imake
for makefile generation. As I recall, it was basically the c preprocessor syntax to generate the make files.在编译 Haskell 代码之前,C 预处理器也可以由 Glasgow Haskell 编译器 (GHC) 调用,通过传递
-cpp
标志。The C preprocessor can also be invoked by the Glasgow Haskell Compiler (GHC) prior to compiling Haskell code, by passing the
-cpp
flag.您可以在另一种语言的编译器中实现 C 预处理器。
您可以使用它来预处理任何类型的文本文件,但为此目的还有更好的东西。
You could implement the C preprocessor in the compiler for another language.
You could use it to preprocess any sort of text file, but there's much better things for that purpose.
基本上它的意思是预处理器与 C 语法无关。 它们基本上是遵循一组规则的简单解析器。 因此,您可以像使用 sed 或 awk 一样使用预处理器来完成一些愚蠢的任务。 不要问我为什么你想这样做。
例如,在一个文本文件上:
然后运行预处理器 & 你会得到的。
Basically what it's saying is that preprocessors have nothing to do with C syntax. They are basically simple parsers that follow a set of rules. So you could use preprocessors kind of like you'd use sed or awk for some silly tasks. Don't ask me why you'd ever want to do it though.
For example, on a text file:
Then you run the preprocessor & you'd get.
您可以直接调用 CPP:
而不是通过 gcc 调用它:
但是请注意,正如同一篇维基百科文章中提到的,C 预处理器的语言并不真正适合通用用途:
您是否考虑过尝试使用更灵活的宏处理语言,例如前面提到的 m4?
You can call CPP directly:
Rather than calling it through gcc:
Do note however that, as mentioned in the same Wikipedia article, C preprocessor's language is not really equipped for general-purpose use:
Have you considered dabbling with a more flexible macro processing language, like the aforementioned m4 for instance?
例如,汇编器。 虽然许多汇编器都有自己的 #include 头文件和 #define 宏的方法,但为此使用 C 预处理器可能会很有用。 例如,GNU make 具有隐式规则,可以在将 *.s 文件提供给 GNU 汇编器(“as”)之前,通过运行预处理器(“cpp”)将 *.S 文件转换为 *.s 文件。
For example, Assembler. While many assemblers have their own way to #include headers and #define macros, it can be useful to use the C preprocessor for this. GNU make, for example, has implicit rules for turning *.S files into *.s files by running the preprocessor ('cpp'), before feeding the *.s file to the GNU assembler ('as').
是的,可以通过 gcc 预处理器(例如“gcc -E”)解析您自己的语言来完成。
我们在工作中用我们的特定语言做到了这一点。 它有很多优点:
...以及 c 处理器中的其他内容。
但是,您还继承了不安全的 C 结构,并且拥有未与您的主语言集成的预处理器考虑一下最小宏并执行以下操作:
想想在 min 函数之后 a 和 b 会有什么值?
对于您引入的非类型常量也是如此,
请参阅 更安全的C书了解详细信息。
Yes, it can be done by parsing your own language through the gcc preprocessor (e.g. 'gcc -E').
We have done this on my job with our our, specific language. It has quite some advantages:
... and the other things in the c processor.
HOWEVER, you also inherit the unsafe C constructions, and having a preprocessor not integrated with your main language is the cause of it. Think about the minimum macro and doing something like :
Just think what value a and b will have after the min function?
Same is true about the non-typed constants that you introduce
See the Safer C book for details.
许多 C 编译器都有一个标志,告诉它们只进行预处理。 对于 gcc,它是 -E 标志。 例如:
将输出:
对于其他 C 编译器,您必须检查手册以了解如何切换到仅预处理模式。
Many C compilers have a flag that tells them to only preprocess. With gcc it's the -E flag. eg:
will output:
With other C compilers you'll have to check the manuals to see how to swithc to preprocess-only mode.
通常,您可以使用仅进行预处理的选项来调用 C 编译器(并忽略任何 #line 语句)。 举个简单的例子:
我们用预处理语句定义一个 PHP 源文件。 然后我们可以对其进行预处理(gcc 也可以做到这一点):
由于
DEBUG
不是定义的,因此第一个echo
被删除。 另外,以 # 开头的行是 PHP 中的注释,因此您不必为“调试”构建对它们进行预处理。编辑:既然您询问了宏。 这也很好用,可以用来生成样板代码等。
Usually you can invoke the C compiler with an option to preprocess only (and ignore any #line statements). Take this as a simple example:
We define a PHP source file with preprocess statements. We can then preprocess it (gcc can do this, too):
Since
DEBUG
is not the defined the firstecho
is stripped. Plus here is that lines beginning with # are comments in PHP so you don't have to preprocess them for a "debug" build.Edit: Since you asked about macros. This works fine too and could be used to generate boilerplate code etc.
使用微软的编译器,我认为(我只是查了一下,没有测试过)它是/P 编译器选项。
其他编译器可能有类似的选项(或者,对于某些编译器,预处理器实际上可能是不同的可执行文件,它通常由编译器隐式运行,但您也可以单独显式运行)。
Using Microsoft's compiler, I think (I just looked it up, haven't tested it) that it's the /P compiler option.
Other compilers presumably have similar options (or, for some compilers the preprocessor might actually be a different executable, which is usually run implicitly by the compiler but which you can also run explicitly separately).
假设您正在使用 GCC,您可以获取任何纯旧文本文件,无论其内容如何,然后运行:
文件中的任何预处理器指令都将由预处理器处理,然后 GCC 将退出。
关键是文本文件的实际内容是什么并不重要,因为预处理器关心的只是它自己的指令。
Assuming you're using GCC, You can take any plain old text file, regardless of its contents, and run:
Any preprocessor directives in the file will be processed by the preprocessor and GCC will then exit.
The point is that it doesn't matter what the actual content of the text file is, since all the preprocessor cares about is its own directives.
我听说有人在 Ada 代码上使用 C 预处理器。 Ada 没有预处理器,所以如果你想预处理,你必须做类似的事情你的代码。
然而,不给它一个是一个有意识的设计决定,所以这样做是非常不符合 Ada 标准的。 我不会建议任何人这样做。
I have heard of people using the C pre-processor on Ada code. Ada has no preprocessor, so you have to do something like that if you want to preprocess your code.
However, it was a concious design decision not to give it one, so doing this is very un-Ada. I wouldn't suggest anyone do this.