Fortran and short-circuit logic
Never assume that eager or short-circuit evaluation of logical statements will occur in Fortran.
Fortran standards from Fortran I (1957) through Fortran 2018 do not mandate or prohibit short-circuit logic. That has resulted in some compilers (e.g. Gfortran) sometimes using short-circuit logic, while other compilers (e.g. Intel) do not use short circuit logic. This causes breakage when the programmer tests with one Fortran compiler handles compound logic with eager evaluation, but other compiler uses short-circuit evaluation.
Compilers not short-circuiting (standard Fortran behavior):
- Gfortran
-O0
- NAG
- Intel
Short circuiting (non-standard behavior)
- Gfortran
-O1
or higher
Proper handling of compound logic in Fortran: one should carefully avoid assumptions that either eager or short-circuit evaluation of compound logical statements will occur, because neither is guaranteed by any Fortran standard.
Assuming eager evaluation of Fortran logical statements, this can cause breakage where a function that’s part of the statement has side effects.
For example, a function that modifies a module variable, or simply an intent(inout)
variable will find those variables unmodified if a compiler uses short-circuit logic.
Fix: break up the compound if
statement so that the function is always evaluated (e.g. just before the if
statement).
Assumptions that short circuit evaluation occurs commonly causes breakage of present(arg)
for optional :: arg
optional dummy arguments.
subroutine myfun(a,b)
real, intent(inout) :: a
real, intent(in), optional :: b
! don't do this!
if (present(b) .and. b < 0) a = b*a
! instead, do this:
if present(b) then
if (b < 0) a = b*a
endif