6. Using Modules
As programs grow larger it becomes less convenient to use a single file for the source code. Also it is very often the case that the functions and subroutines you have written can be used in more than one program. We need a way to organise the source code to make this easy to do. In this section we will look at modules which enable the program to be split between multiple files and make it easy to “re-use” the code you write in different programs.
6.1 Modules
Modules are a very useful tool when we split programs between multiple files. Modules give us a number of advantages:
1. The module is useful for defining global data, and may be used as an alternative way of transmitting information to a routine.
2. The variables, etc., declared in a module may be made available within any routines at the choice of the programmer.
3. Modules can be imported for use into another program or subroutine. Functions and variables defined in the module become available for use. The compiler is also able to cross-check the calls to subroutines and functions and use of variables just as if they had been defined as internal routines.
The definition of a module is
module name
[statement declarations]
[contains
[subroutine and function definitions] ]
end module [name]
The module is incorporated in the program segment or routine in which it is to be used by the use statement:
use name
We should now have a look at some examples. Let’s return to the swapmain program from section 5.3 and implement this in two files using modules. First edit the file swapmain.f90 and to contain:
Now in the second file, called swapmod.f90 the module is defined: module swapmod
f95 -c swapmod.f90
The swapmod.o file contains the compiled code for all the routines in the swapmod.f90 file. When you compile a module an extra file called name.mod is created. This file is needed for as long as you want to include the module in programs.
Within the module you may define as many routines as you like; they are all included with the same use statement.
Let us now look at an example which makes use of modules to provide global data. Again this is a rather contrived example designed to illustrate as simply as possible the use of modules. This time let’s have three files.
f95 -c gd.f90
f95 -c setval.f90
f95 -o testset testset.f90 gd.o setval.o
These two examples, although simple, illustrate the usefulness of modules.
6.2 public and private attributes
The examples of modules in the previous section were quite simple. In general you are likely to want a module which not only declares some global data, but also defines routines in the same module. However we may want to differentiate variables which are global and available in all routines in which the module is used, as we saw in the last section, and variables which are to be global only within the module (i.e. used by all the routines in the module, but not available in the routines or program segments which include the module via the use statement). We can in fact achieve this using the private and public attributes. For example the variable a_g in the following will be available in all program segments including the module in which this definition occurs, whereas the variable b is a global variable only within the current module
real, public :: a_g
real, private :: b
The default is for variables is to be public.