9.1 单独编译(3)
编译器首次遇到该文件时,名称COORDIN_H_没有定义(我们根据include文件名来选择名称,并加上一些下划线,以创建一个在其他地方不太可能被定义的名称)。在这种情况下,编译器将查看#ifndef和#endif之间的内容(这正是我们希望的),并读取定义COORDIN_H_的一行。如果在同一个文件中遇到其他包含coordin.h的代码,编译器将知道COORDIN_H_已经被定义了,从而跳到#endfi后面的一行上。注意,这种方法并不能防止编译器将文件包含两次,而只是让它忽略除第一次包含之外的所有内容。大多数标准C和C++(www.cppentry.com)头文件都使用这种防护(guarding)方案。否则,可能在一个文件中定义同一个结构两次,这将导致编译错误。
程序清单9.2 file1.cpp
程序清单9.3 file2.cpp
将这两个源代码文件和新的头文件一起进行编译和链接,将生成一个可执行程序。下面是该程序的运行情况:
顺便说一句,虽然我们讨论的是根据文件进行单独编译,但为保持通用性,C++(www.cppentry.com)标准使用了术语翻译单元(translation unit),而不是文件;文件并不是计算机组织信息时的唯一方式。出于简化的目的,本书使用术语文件,您可将其解释为翻译单元。
多个库的链接
C++(www.cppentry.com)标准允许每个编译器设计人员以他认为合适的方式实现名称修饰(参见第8章的旁注"什么是名称修饰"),因此由不同编译器创建的二进制模块(对象代码文件)很可能无法正确地链接。也就是说,两个编译器将为同一个函数生成不同的修饰名称。名称的不同将使链接器无法将一个编译器生成的函数调用与另一个编译器生成的函数定义匹配。在链接编译模块时,请确保所有对象文件或库都是由同一个编译器生成的。如果有源代码,通常可以用自己的编译器重新编译源代码来消除链接错误。