对于编译前的C程序,即在预处理完成后生成哪个文件(扩展名是什么)?
答案 0 :(得分:8)
它依赖于编译器。默认情况下,大多数编译器不会生成中间预处理器文件。
使用gcc
,如果添加-save-temps
选项以获取中间文件,则预处理器的输出将转储到.i
文件中。使用-E
选项(仅执行预处理),在没有-o
指定输出文件的情况下,结果将转储到stdout
。
答案 1 :(得分:1)
在大多数当前编译器中(例如GCC或Clang/LLVM) - 并且出于性能原因 - C/C++ preprocessor是编译器的内部部分(在GCC中)它是libcpp/并且是一个库...),因此没有预处理的表单输出到文件中。
在最初的C或原型C编译器(1970年代的PDP-8)中,内存非常小(64千字节!),这样的组织是不可能的,预处理器是一个单独的程序{{1 }}
今天,我们的笔记本电脑有几千兆字节的内存,通常比预处理的格式(您提供给编译器的最大源文件)要大得多。因此,当前的编译器会保留整个translation unit的内部表示,并且能够完全optimize(inter-procedural optimizations,包括内联)。
所有编译器都保留abstract syntax tree(AST)的几种形式;编译器的大部分工作不是parsing或code generation,而是将AST的一些内部表示转换为另一个内部表示(本身进一步转换)。在GCC中,大多数优化工作都是GIMPLE形式。您可以通过添加自己的优化传递来扩展编译器,例如以MELT
编码反过来,这种技术演变使我们的编程语言的定义(演变)受到了影响,最近的C++11是为非常优化的编译器而设计的。最近关于C ++ 11的样式引导或编码提示是预先假定的(并且仅仅因为非常有效的优化而有意义。)
您仍然可以通常调用编译器来吐出预处理的表单,例如使用/lib/cpp
,在单独的文件中(通常带有后缀gcc -C -E source.c > source.i
或.i
,这样的后缀可以为构建器所知,如.ii
)
答案 2 :(得分:1)
C程序到Linux可执行文件的4个阶段之旅:
点击此链接了解详情C program compilation process
答案 3 :(得分:0)
>gcc -E fname.c >fname.x
/ fname.x是保存的预处理输出 /
预处理阶段会发生以下四件事。
1> header file inclusion
2>comment removal
3>macro substitution
(例如,如果您拥有#fenine NUM 10,那么您使用NUM代码的代码将替换为10)
4> conditional compilation
(例如
#if 0
...
some code
...
#endif
由于“#if 0”的计算结果为0,因此其下的代码永远不会执行。因此,其下的代码不包含在预处理输出中