2.1.3 编译过程

2013-10-07 14:18:46 · 作者: · 浏览: 65

2.1.3   编译过程

为了用C/C++(www.cppentry.com)编程(www.cppentry.com),应该了解编译过程的步骤和所需工具。某些语言(特别是C/C++(www.cppentry.com))编译时,首先要对源代码执行预处理。预处理器(preprocessor)是一个简单的程序,它用程序员(利用预处理器指令)定义好的模式代替源代码中的模式。预处理器指令用来节省输入,增加代码的可读性。(C++(www.cppentry.com)程序设计并不鼓励多使用预处理指令,因为它可能会引起一些不易发现错误,这些将在本书的后面分析)。预处理过的代码通常存放在一个中间文件中。

编译一般分两遍进行。首先,对预处理过的代码进行语法分析。编译器把源代码分解成小的单元并把它们按树形结构组织起来。表达式“A+B”中的“A”、“+”和“B”就是语法分析树的叶子节点。

有时候会在编译的第一遍和第二遍之间使用全局优化器(global optimizer)来生成更短、更快的代码。

编译的第二遍,由代码生成器(code generator)遍历语法分析树,把树的每个节点转化成汇编语言或机器代码。如果代码生成器生成的是汇编语言,那么还必须用汇编器对其汇编。两种情况的最后结果都是生成目标模块(通常是,一个以.o或.obj为扩展名的文件)。有时也会在第二遍中使用窥孔优化器(peephole optimizer)从相邻一段代码中查找冗余汇编语句。

用“object”(目标)一词表示一段机器代码是一种不合适的选择,在面向对象程序设计之前这一名词就普遍使用了。在讨论编译时“object” 与“goal”(目标)含义相同,而在面向对象程序设计中,它的意思是“一个有边界的事物”。

连接器(linker)把一组目标模块连接成为一个可执行程序,操作系统可以装载和运行它。当某个目标模块中的函数要引用另一目标模块中的函数或变量时,由连接器来处理这些引用;这就保证了所有需要的、在编译时存在的外部函数和变量仍然存在。连接器还要添加一个特殊的目标模块来完成程序启动任务。

连接器能搜索称为“库”的特殊文件来处理它的所有引用。库将一组目标模块包含在一个文件中。库由一个被称为库管理器(librarian)的程序来创建和维护。