Modules

15.1 Defining & using modules

module constants
  use, intrinsic :: iso_fortran_env, only: dp => real64
  implicit none
  private                                  ! default: everything private
  public :: dp, pi, g, circle_area         ! explicit public API

  real(dp), parameter :: pi = 4.0_dp * atan(1.0_dp)
  real(dp), parameter :: g = 9.80665_dp
  real(dp), protected :: counter = 0.0_dp  ! readable outside, writable only inside

contains

  pure real(dp) function circle_area(r)
    real(dp), intent(in) :: r
    circle_area = pi * r**2
  end function circle_area

end module constants

program use_constants
  use constants, only: dp, pi, area => circle_area   ! only + rename
  implicit none
  print *, pi, area(1.0_dp)
end program use_constants

15.2 What modules provide

Encapsulation with private/public/protected.

Explicit interfaces for all module procedures.

Shared global data (replacing COMMON blocks) — use sparingly.

Types, constants, generic interfaces, operator overloading.

Compilation produces .mod files that dependent units need → compile modules before the code that uses them.

15.3 Intrinsic modules

kinds (int32, real64...), units, iostat_end, compiler_version C interoperability (§25)

ieee_arithmetic, ieee_exceptions, ieee_features IEEE 754 control (§27)

OpenMP runtime (not standard, but universal)

15.4 Module design tips

One module per file, file named after the module.

private by default, export a minimal API.

Use only: lists in use statements to make dependencies explicit.

Avoid circular dependencies (submodules help, §24).