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
gamma are not fully defined.
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
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.
contains we have definitions of four functions
that correspond to Q(a, x),
Of these only the first, Q(a, x) is correctly
implemented, whereas the remaining three functions simply return
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
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.o. The first file contains specifications of all public objects defined in the module. This is a data file, but you can get a glimpse of what it contains if you run strings on it:
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 eulerin the main program. File
euler.ocontains 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 chi.f90, i.e., if I call function goodness with one argument instead of two: