Now let us have a look
at the file that contains module `euler`.
Figure 2.11 lists the content of file `euler.f90`,
on which I have saved the skeleton of the module.

This is only a skeleton, because functions `small_gamma`

,
`big_gamma`

, and `gamma`

are not fully defined.
They
are not even correctly defined. But this skeleton covers all
mechanics of the program. It can be compiled and linked with
the main program, and the main program can be run - just to
ensure that the mechanics are correct.

Then we can worry about defining functions , and .

The module program looks much like the main program,
but it begins with the word `module`

. In the preamble
you can define any global variables or constants that
need to be accessed either by the module's functions or by
programs calling the module. Here we only define the
constant `long`

.

The statement `contains`

separates the first part
of a module,
that is allowed to contain specification statements only,
from a part that contains definitions of module subprograms.
This statement can be used in a main program too, in which case
it would separate specification and *procedural*
parts of the main program from its subprograms.

Following `contains`

we have definitions of four functions
that correspond to *Q*(*a*, *x*),
,
,
and .
Of these only the first, *Q*(*a*, *x*) is correctly
implemented, whereas the remaining three functions simply return
*a*.

Observe that the dummy parameters, *a*, and *x*, are
declared
to have their

intent(in)This tells Fortran compiler that they are not meant to be changed by the subprogram. Consequently the compiler may implement some optimisations, and it can also check the subprogram for any inadvertent attempt to change the values of the

`intent(in)`

parameters.
The body of the module ends with the statement

end module euler

Since all mechanics of the module should now be fully functional, I can demonstrate to you how it all works. In order to compile and link the whole program, the module must be compiled first:

gustav@blanc:../src 14:33:08 !546 $ f90 -c euler.f90 gustav@blanc:../src 14:33:14 !547 $ ls -FCs euler* 3 euler.M 1 euler.f90 2 euler.o gustav@blanc:../src 14:33:18 !548 $Under Solaris 2.6 the compilation creates two files:

`euler.M`

and `euler.o`

.
The first file contains specifications of all gustav@blanc:../src 14:35:01 !552 $ strings euler.M EULER SELECTED_REAL_KIND EULER LONG _SELECTED_REAL_KIND_ @STACK @DARGS GOODNESS GOODNESS.in.EULER @STACK @DARGS SMALL_GAMMA SMALL_GAMMA.in.EULER @STACK @DARGS BIG_GAMMA BIG_GAMMA.in.EULER @STACK @DARGS GAMMA GAMMA.in.EULER gustav@blanc:../src 14:35:55 !553 $This is the file that is looked up by the Solaris Fortran compiler when it encounters the statement

`use euler`

in the main program. File `euler.o`

contains a compiled code that corresponds to the module's subprograms.
That is the file that we will have to link our program with.
In summary, `euler.M` is used during compilation of `chi.f90`,
and `euler.o` is used when linking `chi`.

Under IRIX, the module interface file generated by the compiler
will be called `EULER.kmo`

. This file is human readable,
and this is what it looks like:

gustav@barruc:../src 15:40:47 !501 $ cat EULER.kmo internalinterface function GOODNESS ( A, X ) intent ( in ) A, X doubleprecision A, X doubleprecision GOODNESS end function GOODNESS function SMALL_GAMMA ( A, X ) intent ( in ) A, X doubleprecision A, X doubleprecision SMALL_GAMMA end function SMALL_GAMMA function BIG_GAMMA ( A, X ) intent ( in ) A, X doubleprecision A, X doubleprecision BIG_GAMMA end function BIG_GAMMA function GAMMA ( A ) intent ( in ) A doubleprecision A doubleprecision GAMMA end function GAMMA end interface integer LONG parameter (LONG = selected_real_kind (9, 99)) intrinsic SELECTED_REAL_KIND gustav@barruc:../src 15:40:54 !502 $

Program `chi` is now compiled, linked, and run as follows:

gustav@blanc:../src 14:39:26 !558 $ f90 -c chi.f90 gustav@blanc:../src 14:39:33 !559 $ f90 -o chi chi.o euler.o gustav@blanc:../src 14:40:21 !560 $ ./chi < chi.dat a = 1.808 +- 0.088 b = 0.515 +- 0.014 chi^2 = 15.310 Q = 1.000 STOP 0 gustav@blanc:../src 14:40:25 !561 $

Now observe what is going to happen if I replace

q = goodness( (n - 2.0_long) / 2.0_long, chi_2 / 2.0_long )with

q = goodness( (n - 2.0_long) / 2.0_long )in

The compiler, having found about the definition of function