Program Construction and Management |
4 |
![]() |
Units
For many reasons, it is often inconvenient to store a program in a single file, as in the case of a very large program.
program include (output); #include "includefile" |
the line #include "includefile" is a compiler directive to cpp(1), the Pascal compiler's preprocessor. The directive instructs cpp(1) to find the file includefile and copy it into the stream before continuing.
begin writeln ('Hello, world.') end. |
In this example, the include file contains the entire program. In reality, an include file probably contains a set of variable or procedure declarations. include files are often used when a set of declarations needs to be shared among a number of programs.
Using Program Units and Module Units
There are two kinds of units:
program program_unit (output); procedure say_hello; extern; begin say_hello end. |
module module_unit; procedure say_hello; begin writeln ('Hello, world.') end; |
Every program must have one and only one program unit; a program can have any number of module units. Any unit can call procedures declared in any other unit; each unit must have external declarations for every procedure it uses that is not defined in that unit.
Compiling with Units
Consider the units given in the previous section, "Using Program Units and Module Units." You can compile and link these units on a single line by executing the following command, which then produces the executable, a.out.
hostname% pc program_unit.p module_unit.p
You can also separate the compilation and linking or loading steps, as follows:hostname% pc program_unit.p -c
In this case, you call pc on each unit with the "compile only" option (-c), which produces an object file with the extension .o. When you use this option, the compiler driver does not call the linker, ld. You then call pc a second time, giving the names of the object files, and pc calls pc3 to check for name and type conflicts before calling the linker.
hostname% pc module_unit.p -c
hostname% pc program_unit.o module_unit.o
Using Units and Header Files
A complex program may have many routines defined in modules. Each routine must have a declaration (for example, procedure proc; extern;) in each file that calls the routine. The easiest way to be sure that you have a correct and consistent set of declarations is to create a header file.
program program_unit2 (output); #include "header.h" begin say_hello end. |
In this case, the content of header.h is very simple:
procedure say_hello; extern; |
In a real program, header.h would probably contain many declarations and would be included in several modules. Aside from routine declarations, header files often contain constant, type, and variable declarations.
Sharing Variables Between Units
Variables that are global across a unit (that is, not declared locally in a routine) can be public or private. A public variable can be shared by any unit that is linked to the unit that declares the variable. A private variable cannot be shared.
program program_unit3 (output); public var x : integer; private var y : integer; |
When you do not use public or private, variables are public by default. However, when you compile with the -xl option, variables are private by default.
program program_unit3 (output); var x : integer; procedure say_hello; external; begin for x := 1 to 5 do say_hello end. |
Here is a module unit that declares a variable with the same name:
module module_unit3; var x : integer; procedure say_hello; begin writeln ('Hello, world for the', x, ' time.') end; |
By default, both definitions of variable x are public. Thus, when you compile and link the program and module units, references to x refer to the same variable, as follows:
If you compile the program giving the -xl option, the variables are private by default, as follows:
You can get the same effect by explicitly declaring the variable in a private var section. Similarly, when you use -xl, you can create public variables by declaring them in a public var section.
Libraries
You can use a module unit as a library of useful functions. The simplest way to do so is to create a source file containing the definitions of your library routines and then compile it using the -c option. You can then link the resulting .o file to any number of files. For convenience, you probably should create a header file containing the routine declarations for the library.
See the Solaris documentation on the linker and libraries for information on creating archived and shared libraries.