Here is my perspective (based on trying to refactor a lot of old code) on GOTO’s.
Use of GOTO’s in old code generally falls into three catagories.
- conditional branching (now done with if-then-else statements or select case)
Example:
if (a < b) GO TO 10
some code
GO TO 20
10 continue
some more code
20 continue
which would be replaced today with
if (a>=b) then
some code
else
some other code
endif
- imbedded loops (now done with either DO WHILE or unindexed DO)
Example
10 continue
if (a > amax) Go To 20
some code
a = a + da
GO TO 10
20 continue
which would be replaced by
do while (a<=amax)
some code
a = a+da
end do
- error control (as previously noted) - jumping to the end of a routine to do error handling/printing before exiting. I’ve found that in many cases this is the hardest to remove and is probably not worth the effort. In fact I consider this case the one remaining viable use for GO TOs in modern Fortran programming.
One caveat on trying to replace the GO TO cases that map to if-then-else blocks. If you don’t want to move large blocks of code around, you have to change the conditional clause (say from a.LT.b to a.GE.b) which can lead to some surprising results after the compiler does its optimization thing. You can change the order of execution which can also lead to changes in your results (usually small but still apparent). If your refactored code has to produce output that is bit-wise identical to the old code, you have to be very careful about how you move things around.