Search code examples
fortranformatgoto

Avoiding the GOTO paradigm in Fortran FORMAT when reading/writing


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?


Solution

  • In a formatted data transfer statement there are three ways to specify the format to use (Fortran 2018 R1215):

    • referencing a labelled FORMAT statement
    • using a (default) character expression
    • with a * (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...) ...