Separate Compilation |
5 |
![]() |
In separate compilation, a program is divided into several units that can be separately compiled into object (.o) files. The object files are then linked using pc, which invokes pc3 to check for the consistent use of global names and declarations across the different units, and then invokes ld(1) to link and load the units. You can also give pc the names of all the units at once, in which case pc compiles all the units, checks for consistency, and links the units in one step.
Working with Units
Pascal provides two types of source files or units: the program unit and the module unit. Using Program Units
The program unit is the source program with the program header. It has the following syntax:<program unit> ::= <program heading> <declaration list> <program body>
Each program you write can have only one program unit. The program body is the first code that Pascal executes. Using Module Units
A module unit is a source program that does not have a program header. It has the following syntax:<module unit> ::= [ <module heading> ] <declaration list>
The module heading contains the reserved word module followed by an identifier:<module heading> ::= [ 'module' <identifier> ';' ]
For example:
module sum; |
This is a legal module heading. The module heading is optional.
Sharing Variables and Routines Across Multiple Units
Pascal supports three methods of sharing variables and routines between units:
The following sections describe these methods.
Using extern Option to Share Routines
If a program or module calls a procedure not defined in that unit, you must declare it with either the extern or external routine option. For instance, in the previous example, the procedure proc is defined in shrvar_mod.p, but used in shrvar_prog.p. Thus, it is declared as external in shrvar_prog.p. Also, proc must also be defined as public in shrvar_mod.p, which is the default. Using include Files to Share Variables and Routines
The include file contains the declarations for the program. Placing all program declarations in a single file makes your program more consistent and easier to maintain.
The module unit, inc_mod.p, which also includes the file include.h
|
module inc_mod; #include "include.h" procedure proc; begin writeln('From PROC : ', global); global := global + 1 end; { proc } |
The include file, include.h
|
var global : integer; procedure proc; extern; |
Using the -xl Option
When you use the -xl option, variables and top-level procedures and functions declared in the program unit default to private. Look at the difference when you compile and execute shrvar_prog.p and shrvar_mod.p with -xl. See the source code in "Sharing Public Variables" on page 81.
Without -xl, the variable global in shrvar_mod.p is treated as public; here, global is treated as private. Thus, the assignment:
global := global + 1;
is not reflected in shrvar_prog.p; instead, each file uses its own private copy of global. Using public var Declarations
The following examples uses the public attribute in the var declaration to make global public when you compile your program with -xl.
Using the define Variable Attribute
This example makes global public using the define attribute of the variable declaration.
Using the define Declaration
This example defines global in the module defvar_mod2 using the define declaration. The advantage of using the define declaration over the define variable attribute is that the define declaration can be easily converted to use include files.
Using include Files
In the following example, the extern declaration for the variable global is in the include file, inc_prog2.p, and is therefore included in both files. The define declaration in file inc_mod2.p cancels the extern definition.
The module unit, inc_mod2.p
|
module inc_mod2; define global; %include "include2.h"; procedure proc; begin writeln('From PROC : ',global); global := global + 1; end; { proc } |
The include file, include2.h
|
var global : extern integer; |
Using extern
In the previous example, the extern definition for variables is put into an include file and then shared. You can do the same for the extern procedure definition. In doing so, you must also declare the variable with a define declaration in the module that defines the procedure. This declaration nullifies the effect of the extern declaration.
The program unit, ext_prog.p
|
program ext_prog; %include "extern.h"; begin global := 1; writeln('From MAIN, before PROC: ',global); proc; writeln('From MAIN, after PROC: ',global); end. { ext_prog } |
The module unit, ext_mod.p
|
module ext_mod; define global, proc; %include "extern.h"; procedure proc; begin writeln('From PROC : ',global); global := global + 1; end; { proc } |
The include file, extern.h
|
var global : extern integer; procedure proc; extern; |
Sharing Declarations in Multiple Units
Using extern and external directives for procedure and function declarations, you can optionally specify the source language of a separately compiled procedure or function. For example, extern fortran directs the compiler to generate calling sequences compatible with the FORTRAN compiler from SunSoft. Then, external c directs the compiler to generate calling sequences compatible with SunSoft C compiler.
When you compile your program with the -xl option, you can also use nonpascal to declare non-Pascal routines when porting DOMAIN programs written in DOMAIN Pascal, FORTRAN, and C.