Chapter 13 — Teaching Notes
One-line purpose. Turn optimistic code into robust code: ask whether each operation worked, halt deliberately when it did not, arm the compiler to catch what you missed, and check your own beliefs — the one Part II topic no track should skip.
Key ideas to emphasize
- One pattern, many places.
iostat(I/O),stat(allocation), and coarraystat=are the same idea — ask, then decide. Teach the shape once and students recognize it everywhere. This is the spine of §13.1. - The exit code is a promise to the shell. Students think a program ends when it prints; it actually ends
by reporting an integer that automation reads.
error stopwith a chosen code is how you tell the truth about failure. Theecho $?demo makes this concrete and lands hard. - Make the silent failure loud. The chapter's method (Case Study 1) is the transferable skill: reproduce,
-ffpe-trapto make it loud, read the backtrace, gdb to inspect, then fix + guard. Walk it live. - An assertion is an executable belief. The distinction that matters:
stat/iostathandle what the world does to you (expected); assertions catch what you got wrong (the "impossible"). Do not let students use assertions for expected errors or status returns for logic bugs. - Implicit
saveis the trap they will actually hit.integer :: n = 0in a procedure is saved, not reset. Demo the 1,2,3-vs-1,1,1 counter; it is memorable and genuinely surprising.
Misconceptions to preempt
- "Fortran zeroes my locals." (No — uninitialized locals hold garbage; often zero by luck, hence platform-dependent bugs.)
- "
error stopandstopare the same." (Different termination kind and exit code; different parallel semantics.) - "
==on reals is fine if the values 'should' be equal." (Almost never true for computed reals; use a tolerance.) - "
-fcheck=allshould be on in production." (No — it costs speed; strip it for the production run, keep the cheaper-fbacktrace/-ffpe-trap.) - "A NaN in the output means the physics is unstable." (Often it is a mundane unset/unvalidated value — Case Study 1's whole point.)
- "Trap all FP exceptions." (Never
underflow/inexact— they fire in correct code.)
A live demonstration (8 minutes)
- Compile the
bounds_demo(§13.3) plainly and run — it prints something plausible. Then recompile with-fcheck=all -g— a runtime error with a line number. The gap is the lesson. - Compile a two-line divide-by-zero with and without
-ffpe-trap=zero -fbacktrace. Without: printsInf, continues. With:SIGFPEat the line. (Do not claim exact message text — versions differ; the behavior is the point.) - Run the implicit-save counter (
example-03) and let the 1,2,3 output surprise them before you explain why.
Class-time budget (~50 min)
- 8 min: errors as values —
iostatrecap →stat/errmsg(§13.1). - 8 min:
stopvserror stop, exit codes,echo $?(§13.2). - 12 min: the three flags, with the two live demos (§13.3).
- 6 min: gdb/valgrind — what each is for (§13.4); keep it brief, it is reference material.
- 10 min: assertions + defensive programming, the executable-belief idea (§13.5).
- 6 min: the usual suspects, esp. implicit
saveand integer overflow (§13.6), and the Project Checkpoint.
Prerequisites to review
Ch. 7 (iostat/iomsg, namelist) — this chapter generalizes it; Ch. 5 (arrays, bounds, allocatable);
Ch. 9 (field_t); Ch. 11 (dangling pointers, allocatable-vs-pointer) — both spaced-review targets. A quick
recap of iso_fortran_env (error_unit, real64, int32/int64) pays off.
Connections
Back: Ch. 3 (integer division), Ch. 7 (iostat), Ch. 11 (dangling). Forward: Ch. 14 (C error conventions —
errno/return codes — vs Fortran's model), Ch. 20 (NaN/Inf, ieee_arithmetic), Ch. 24 (CFL blow-up as an
error to catch), Ch. 30 (debug vs release flags), Ch. 37 (assertions complement tests). Naming these payoffs
now motivates the discipline.