Library › Fortran Programming › Part I: Foundations › Chapter 4: Control Flow — IF, SELECT CASE, DO Loops, and Making Decisions › Chapter 4 — Key Takeaways (Control Flow)
Chapter 4 — Key Takeaways (Control Flow)
A one-page reference to the constructs that let a Fortran program decide and repeat. Modern, block-structured,
no goto.
The constructs at a glance
Construct
Skeleton
One-line job
if construct
if (c) then … else if (c2) then … else … end if
branch on conditions; first true wins
logical if
if (c) stmt
one guarded statement, no end if
select case
select case (x) / case (…) / case default / end select
dispatch on one discrete value
counted do
do i = a, b, s … end do
loop a known number of times
do while
do while (c) … end do
loop while a condition holds (tested first)
infinite do
do … if (c) exit … end do
loop with a mid-body exit
cycle
cycle / cycle name
skip to the next iteration
exit
exit / exit name
leave the (named) loop
named construct
name: do … / end do name
target exit/cycle at an outer loop
where
where (mask) … elsewhere … end where
masked whole-array assignment
do concurrent
do concurrent (i = a:b) … end do
assert iterations are independent
Operators (the vocabulary of conditions)
Kind
Operators
Relational
== /= < <= > >=
Logical
.and. .or. .not. .eqv. .neqv.
The dots are part of the spelling. A relational or logical expression has type logical.
Which loop should I use?
Situation
Use
I know the iteration count
counted do i = 1, n
Loop until a condition fails, count unknown
do while (c)
Condition can only be tested mid-body (e.g. after computing the new value)
infinite do + exit
Skip some iterations
cycle inside any loop
Break out of an outer loop
name it, exit name
Change part of an array by a condition
where (details in Ch. 5)
Iterations are provably independent
do concurrent (perf payoff in Ch. 29)
select case vs. an if-chain
Use select case when you compare one discrete value (integer/character/logical) against fixed
alternatives; use an if-chain for different conditions.
Labels may be a value case (3), a list case (1, 2, 5), or a range case (60:69), case (:0).
Labels must be disjoint (the compiler enforces it) and the type must not be real.
No fall-through : exactly one block runs — no break to forget, unlike C's switch.
Common pitfalls
Pitfall
Fix
if (x == 0.1_dp) on reals
test a tolerance: if (abs(x - 0.1_dp) < 1.0e-9_dp) (why: Ch. 20)
do t = 0.0, 1.0, 0.1 (real counter)
deleted from the standard; count with an integer, t = t0 + real(step, dp)*dt
bare exit meant to leave an outer loop
name the loop and write exit name
overlapping select case ranges
make labels disjoint (else compile error)
do concurrent with a(i) = a(i-1) + 1
iterations aren't independent — use an ordinary do
writing new forall
obsolescent in 2018 — use where, do concurrent, or a = b*2
Numbers & rules worth memorizing
A counted do i = 1, n runs n times — bounds are inclusive on both ends (unlike Python's range).
The trip count is fixed at loop entry ; changing the bound inside does not lengthen the loop.
The loop counter is always an integer .
Operator precedence in conditions: .not. > .and. > .or. (so
a==0 .and. b/=0 .or. c==0 means (a==0 .and. b/=0) .or. c==0).
select case compiles to a possible jump table (O(1)); an if-chain of k cases averages ~k /2 tests.
Compile flag reminder (from Ch. 2)
$ gfortran -std=f2018 -Wall -fcheck=all -g control.f90 -o control
-fcheck=all catches an out-of-bounds index inside a loop during development (drop it for production runs).
Python / C quick map
Fortran
Python
C
else if
elif
else if
select case (no fall-through)
match / dict
switch (needs break)
do i = 1, n (inclusive)
for i in range(1, n+1)
for (i=1; i<=n; i++)
cycle / exit
continue / break
continue / break
.and. .or. .not.
and or not
&& \|\| !
where (m) a = …
a[m] = … (NumPy)
manual loop
Project piece added this chapter
The heat solver's time-stepping skeleton : a do loop over time steps, and inside it a nested grid sweep
with an if (or cycle) separating boundary points (held fixed) from interior points (updated later).
No numerics yet — the physics lands in Chapter 24 .
The loop nest keeps the first index innermost, the column-major habit that pays off in Ch. 5 and Ch. 27. For a
4×3 grid: 10 boundary points, 2 interior.
← Previous
Case Study 2: Designing the Solver's Control Architecture
Next →
Further Reading: Control Flow