Originale-mail to me for new edition

 

Multiple and indirect unit references

 

The order in which units appear in the uses clause determines the order of their initialization (see The initialization section)and affects the way identifiers are located by the compiler. If two units declare a variable, constant, type, procedure, or function with the same name, the compiler uses the one from the unit listed last in the uses clause. (To access the identifier from the other unit, you would have to add a qualifier: UnitName.Identifier.)

A uses clause need include only units used directly by the program or unit in which the clause appears. That is, if unit A references constants, types, variables, procedures, or functions that are declared in unit B, then A must use B explicitly. If B in turn references identifiers from unit C, then A is indirectly dependent on C; in this case, C needn’t be included in a uses clause in A, but the compiler must still be able to find both B and C in order to process A.

The example below illustrates indirect dependency.

 

program Prog;

uses Unit2;

const a = b;

...

unit Unit2;

interface

uses Unit1;

const b = c;

...

unit Unit1;

interface

const c = 1;

...

 

In this example, Prog depends directly on Unit2, which depends directly on Unit1. Hence Prog is indirectly dependent on Unit1. Because Unit1 does not appear in Prog’s uses clause, identifiers declared in Unit1 are not available to Prog.

To compile a client module, the compiler needs to locate all units that the client depends on, directly or indirectly. Unless the source code for these units has changed, however, the compiler needs only their .dcu (Windows) or .dcu/.dpu (Linux) files, not their source (.pas) files.

When changes are made in the interface section of a unit, other units that depend on it must be recompiled. But when changes are made only in the implementation or other sections of a unit, dependent units don’t have to be recompiled. The compiler tracks these dependencies automatically and recompiles units only when necessary.

 

Topic groups

Programs and units: Overview

Program structure and syntax: Overview

The program heading

The program uses clause

The block

Unit structure and syntax: Overview

The unit heading

The interface section

The implementation section

The initialization section

The finalization section

Unit references and the uses clause

The syntax of a uses clause

Multiple and indirect unit references

Circular unit references

 

See also

Circular unit references

The syntax of a uses clause

Unit references and the uses clause

 

 

译文

 

多重和间接单元引用

 

单元在uses子句中出现的位置决定了其初始化节执行的顺序(初始化节)并且对编译器定位该单元中标识符的方式有影响。如果两个单元声明了同名的变量、常量、类型、过程或函数,那么编译器将根据uses子句中的单元列表从后向前查找,也就是说,列于uses子句中靠后位置的单元,其标识符优先被编译器认可。(要访问其他单元的标识符,可以在标识符前加上限定词,例如:UnitName.Identifier。这样就可以消除编译器自动匹配可能带来的影响。)

uses子句中只需要包括其直接使用的单元。对于程序(program),只需要包括其语句块中直接使用的标识符所在的单元。对于单元,在其接口节使用的标识符所在的单元需要列在其接口节的uses子句中,此时其实现节也可以使用被引用的单元中的公共实体;在其实现节使用的标识符所在的单元需要列在其实现节的uses子句中,此时其接口节中不能使用被引用单元的公共实体。例如,如果单元A引用了在单元B中声明的常量、类型、变量、过程或函数,那么单元A必需通过uses子句显式地使用单元B。如果此时单元B又引用了单元C,那么称单元A间接引用了单元C。在此情况下,单元C不必包括在单元Auses子句中,而为了成功编译单元A,编译器仍必需能找到单元B和单元C

下面给出的例子说明了单元的间接依赖关系:

 

program Prog;

uses Unit2;

const a = b;

...

unit Unit2;

interface

uses Unit1;

const b = c;

...

unit Unit1;

interface

const c = 1;

...

 

在本例中,Prog直接依赖Unit2Unit2直接依赖Unit1。因此Prog间接依赖Unit1。由于Unit1没有出现在Proguses子句中,因此Unit1的标识符对于Prog是不可用的。`

要编译一个客户模块,编译器需要定位该客户依赖的所有单元,包括直接依赖和间接依赖。除非这些单元的源代码发生了改变,否则编译器只需要相应的.dcu文件(Windows)或者.dcu/.dpu文件(Linux)文件,而不需要它们的源(.pas)文件。

在单元的接口节发生改变时,依赖该单元的所有单元必需被重编译。而当单元的实现节或其他部分发生改变时,依赖该单元的单元不必被重编译。编译器会自动跟踪这些依赖关系,并在必要时才重编译相应的客户单元。

 

主题组

程序和单元:概述

程序结构和语法:概述

程序首部

程序的uses子句

单元结构和语法:概述

单元首部

接口节

实现节

初始化节

结束节

单元引用和uses子句

uses子句的语法

多重和间接单元应用

循环单元引用

 

相关主题

循环单元引用

uses子句的语法

单元引用和uses子句

 

 

编者注

编译器根据uses子句自后向前搜索,是为了尽可能优先使用开发者声明的实体,因为Borland提供的单元一般都IDE自动添加到uses子句单元列表中相对靠前的位置。