Modules are subordinate program units that can contain multiple subprograms as well as associated variables.
Modules allow you to organize your code into logically-connected units. It is a form of object oriented programming. They should contain coherent data+procedures. Modules permit data hiding. Variables and subprograms may be kept private from other program units. This prevents another source of error, by reducing the number of variables an outside program can affect or procedures it can call.
Each module has a name that must be unique. A module begins with
and ends with
END MODULE [NAME]
Modules are typically placed into separate files. The file name does not need to be the same as the module name, but the module will be referenced by its name and not by the file name. It is acceptable for short, closely-related modules to be in the same file. If more than one module is in a file, each must be USEd individually.
Modules are brought in via the USE statement
All USE statements must be the first nonexecutable statements after the declaration of the program unit (program, function, subroutine), before any IMPLICIT statement and the variable declarations.
There is no distinct “namespace” for a Fortran module. Names imported into the USEing unit do not acquire a distinguishing name.
Variations of USE
Only specified routines can be brought in with ONLY:
USE mymod, ONLY : f1, f2, s4
Routines can be renamed:
USE mymod, name-here => name-in-module USE stats_lib,sprod=>prod
IMPLICIT NONE at the top applies throughout the module. All variables declared or types defined before a CONTAINS statement are global throughout the module.
Module symbols (variables and names of procedures) can be private . You may also explicitly declare them public but that is the default. The private and public attributes may be added to the declaration, or they may be specified separately with a list following. Private variables are not directly accessible by program units that use the module. Only procedures in the same module can access them. Using PRIVATE or PUBLIC as a separate statement without a list sets or resets the default and may be done only once per module. Public and private may only be set in the specification (interface) portion of the module, not in the procedure bodies.
We will discuss PUBLIC and PRIVATE in more detail when we cover classes.
MODULE mymod USE precisions REAL, PRIVATE :: x, y, z REAL(sp) :: r_fun REAL(dp) :: d_fun PRIVATE ::r_fun,d_fun
where we assume the
precisions module defines the KIND parameters
Subprograms in Modules
Subprograms defined in a module must follow a CONTAINS. The FUNCTION or SUBROUTINE keywords after END are not optional, e.g. END SUBROUTINE is required. The name of the procedure is still optional and some authors recommend not using it, in case it is changed later or to avoid cut and paste errors.
All subprograms in a module have an implicit interface. You should not write an explicit interface for them, and in fact it’s illegal to do so.
module mymod implicit none integer ::Nmax=100000 contains subroutine mysub(a,x) real, dimension(:), intent(in) :: a real, intent(out):: x real, dimension(Nmax) :: b b=x end subroutine function myfunc(x,y) real :: myfunc real,intent(in) :: x,y myfunc=x**2+y end function end module
Modules and Make
A module must be compiled before any other file that uses it. This can create a complicated build environment, so
make or a similar build manager is usually used.
- Type the module
mymodinto a file
mymod.f90. Fortran allows the module and the file to have either the same or a different name, but the name of the module is the name that must appear in the use statement.
- Fill out the subroutine
mysubto set b to 11., then set x to the sum of corresponding elements of a and b. Hint: you can use x=a(:)+b(:size(a)) to avoid a loop.
- Write a main program
Aallocatable, allocates it to 1000, sets its values to
i+3in a loop, then passes it to
mysub. Print the value of
xthat is returned.
- Create a Makefile. If you wish you may copy the example Makefile from the earlier chapter. Make the appropriate changes to the program name, the names of the source files, and the names of the object files. Make the dependency line at the end
Run a make project in Geany or your preferred IDE.