At the university, the professor teaching us Fortran, gave us the following code:
program example
integer year, month, day, inst, kind, ozone
real time
open(unit=1,file='C:\261.dat')
read(1,1000) year, month, day, inst, kind, ozone, time
close(1)
1000 format(i4,1x,i2,1x,i2,1x,i1,1x,i1,1x,i3,1x,f8.3)
end
In this code, the line indexed with 1000 specifies the particular input format. Isn't it something like a GOTO logic? And if yes, what's the most appropriate way to avoid it, in the context of Fortran?
In a formatted data transfer statement there are three ways to specify the format to use (Fortran 2018 R1215):
*
(for list-directed formatting)For example (using a PRINT statement for clarity):
1000 FORMAT (I0)
print 1000, 1 ! Pointing to a FORMAT statement
print '(I0)', 1 ! Literal constant: one form of a character expression
print *, 1 ! List-directed formatting
end
In none of these is the format specification functionally like a GO TO statement.
A GO TO statement changes the flow of execution whereas in the format specification execution remains at the data transfer statement, and then continues to the next statement.
Specifying a label for the format doesn't transfer execution control to that statement, it simply says "use the format given by the statement 1000". This is conceptually like how
character(*), parameter :: CHAR_FMT='(I0)'
print CHAR_FMT, 1
end
says "use the character object CHAR_FMT
(which is declared/defined elsewhere)" as the format.
You'll find may objections to FORMAT statements and (reasonable) suggestions for alternatives, but no objection to using a FORMAT statement is based on "like a GO TO". (And, of course, GO TO statements are not inherently evil.)
Format specifications can be contrasted with the err=
and end=
and eor=
specifiers: these functionally are like GO TO statements:
1 read(unit, fmt, err=10, end=20, eor=20) x
...
! COME FROM 1
20 continue
...
return
! COME FROM 1
10 ERROR STOP "Error in the read"
Such jump-like flow can be alternatively managed with IOSTAT control:
read(unit, fmt, iostat=iostat) x
if (iostat...) ...