Chapter 8 — Key Takeaways (Modules)

A one-page reference. Modules are the container that makes large Fortran possible; keep this beside you until the syntax is automatic.

The anatomy of a module

module name
  use kinds, only: dp        ! import what this module itself needs
  implicit none              ! once, governs the whole module
  private                    ! hide everything by default
  public :: api1, api2       ! expose only the interface
  real(dp) :: state          ! module variable (implicitly SAVE) — keep private
contains
  subroutine api1(...)       ! module procedure: explicit interface for free
    ...
  end subroutine api1
end module name

Core syntax

Construct What it does
module mend module m Define a container of shared entities
use m Import all public entities of m
use m, only: a, b Import only a and b (preferred — documents the dependency)
use m, only: x => a Import a, renamed to x (resolve a clash)
private (bare) Default-hide every entity
public :: a, b Expose the named entities
submodule (m) child Hold the bodies of m's separate module procedures
module function f(...) … A separate module procedure (interface in module, body in submodule)
module procedure fend procedure f Shorthand submodule body (inherits the interface)

Which construct, when

You want to… Use
Share a constant/type/procedure across files a module
A helper used in just one program an internal procedure (contains in the program, Ch. 6)
Hide implementation, expose an API private default + public :: …
Shared mutable state, safely a private module variable + public accessor procedures
Cut rebuild time on a big, volatile module split interface (module) / body (submodule)
Break a genuine circular dependency move the shared need down a layer, or use a submodule

Compile order (the rule newcomers trip on)

  • A module must be compiled before any file that uses it — its .mod must already exist.
  • One gfortran command compiles files left to right, so order the sources: dependencies first.
  • Compile order = a topological sort of the dependency graph: leaves first, program last.
$ gfortran -std=f2018 -Wall kinds.f90 heat_solver.f90 heat_io.f90 heat.f90 -o heat

.mod and .smod files

File Holds Note
foo.o the machine code must be linked
foo.mod the module's public interface read by users at compile time
foo.smod the submodule interface emitted when a module has separate module procedures

Pitfalls

  • Cannot open module file 'x.mod'x was not compiled first (or needs -I<dir>). Compile order, not broken code.
  • Circular dependency (a uses b, b uses a) → will not compile. Refactor the shared need down.
  • Module variables are implicitly save → they persist for the whole run and initialize once.
  • private by exception (private :: helper) → a helper you forget to list leaks into the API. Prefer bare private + public ::.
  • Calling a private module entity from outside → "not found in module." It is invisible on purpose.

Explicit interface — the payoff you get for free

Putting a procedure in a module gives every caller its explicit interface, which: - lets the compiler check argument count, type, rank, and intent at the call site; - is required for keyword args, optional args, and assumed-shape arrays (all from Ch. 6); - lets the optimizer inline and vectorize across the call (Ch. 27).

Why modules replaced COMMON/INCLUDE

COMMON / INCLUDE (legacy, Ch. 17) Module (modern)
Untyped memory overlay; no cross-routine checking One typed, checked, authoritative definition
Can share data only Shares data, types, and procedures
INCLUDE = textual paste kept in sync by hand use imports named, typed entities
Mismatch → silently wrong numbers Mismatch → compile error

Flags introduced

-c compile to a .o without linking · -I<dir> add a directory to the .mod search path.

Project piece added this chapter

The heat solver is split into a module hierarchy: kinds (dp) at the bottom, heat_solver (step) and heat_io (read_config, write_field) as peers above it, and program heat on top. Compile order: kindsheat_solver, heat_ioheat. The physics now lives behind a stable public step, ready for the real stencil in Ch. 24 and the parallel back-ends of Part VIII.