(Thanks to Sergio Gelato for the excellent comments and information,
  and to Dan Pop and Craig Burley)

 The new Fortran 90 standard officially started a slow process of 
 weeding out parts of the older language specification that are 
 obsolete or harmful to good programming. 

 The weeding process must be slow, so that the evolving Fortran 
 standard (and the new compilers) will stay backward compatible 
 with older (legacy) code, long enough that users of such code 
 will be able to conveniently port/rewrite it. 

 This weeding process is important to check the constant growth 
 of the language, adding new features without removing some of the
 older ones makes the language large, and compilers very complex.

 Individual programmers can contribute to this process by stopping 
 to use the 'bad' statements now.

 Harmful statements
 Some standard FORTRAN statements are detrimental to good programming 
 practice by their nature, it's recommended that you don't use them:

    ASSIGN / Assigned GOTO

        Instead of ASSIGN and assigned GO TO, use plain integers and 
        either a computed GO TO or an IF construct; or subroutine calls, 
        if appropriate.

        Fortran 90 provides a SELECT CASE construct that is often more 
        readable than the computed GO TO.


        Usually used to declare the dimensions of arrays whose type was 
        implicitly declared. 

        The recommended practice is to declare all arrays explicitly,
        and to specify the index bounds as part of the (REAL, INTEGER,


        May be tolerated in some special cases of small, tight packages 
        that need to keep internal state, as an alternative to reserving 
        a named COMMON block for this purpose. For larger packages, use 
        a private, named COMMON block instead. Fortran 90's MODULEs offer 
        a much cleaner solution to this class of coding requirements.


        EQUIVALENCE make programs difficult to understand and 
        maintain, it usually hinders data flow analysis and, 
        consequently, automatic compiler optimizations.

        EQUIVALENCE makes different variables and arrays (and even 
        parts of arrays) share the same memory storage, the same 
        variable will have more than one name (and even data type!), 
        and can be accessed by each of them. That behaviour is 
        exploited for various (generally non-portable) tricks 
        involving the internal representation of variables.

        Equivalence was used (before the introduction of virtual 
        memory) to implement program internal 'memory management', 
        a large array was equivalenced dynamically to form the 
        arrays used in the program. Memory was saved in that 
        method because the same part of the primary array was 
        used for different program arrays at different times.

        Yet another use for EQUIVALENCE is to produce an aggregate
        data type similar to Pascal's record or C struct/union,
        e.g. several variables, not necessarily of the same type, 
        can be equivalenced to a large enough array. The resulting
        structure can be passed with the array name, and its 
        'elements' can be accessed with their own names.
        Having the same variable accessed as if it belonged to
        another data type (for special manipulations) can be done 
        by putting the variable in a procedure argument list 
        (or common block) and declaring different data types 
        in different procedures.


        The ARITHMETIC IF statement 

            IF (Expression) Label1, Label2, Label3

        branches to one of the three specified labels according 
        to the value of the expression:

            Condition              Action
            =================      =============
            Expression .LT. 0      GOTO Label1
            Expression .EQ. 0      GOTO Label2
            Expression .GT. 0      GOTO Label3

        The Arithmetic IF is considered harmful.

 Esoteric statements


        NAMELIST is a common extension among FORTRAN 77 compilers, and
        has been incorporated into the Fortran 90 standard. It provides 
        a convenient alternative to writing one's own parser for free-form 
        "keyword=value" input, particularly when it is expected that 
        default values will be taken for most or all keywords. Its main 
        drawbacks are:

           - the external representation of NAMELIST data varies between
             implementations. Some require / as a terminator, some want 
             &END. Some ignore column 1 on input, others don't. On output, 
             some prefer $ to & as a prefix.

           - there is no guarantee that any given FORTRAN 77 compiler will 
             support NAMELIST. Most do, but some implementations have bugs. 
             Very long NAMELISTs should particularly be avoided.

           - Parsing NAMELIST input is relatively costly (the processor 
             needs to do elaborate parsing and table look-up at run-time).

 Obsolete statements
 Some other older FORTRAN statements are obsolete, and there are 
 better replacements for them.

     Statement               Recommended replacement
    ---------------         ------------------------
    PAUSE 'message'         WRITE (*,*) 'message'
                            READ (*,'()')

    PRINT n,...             WRITE (*,n) ...

        It is preferable to use a 'unified' approach and do all 
        I/O with WRITE and READ.

    ACCEPT n,...            READ (*,n) ...
    TYPE n,...              WRITE (*,n) ...

        ACCEPT and TYPE aren't even standard FORTRAN, but rather 
        extensions provided by DEC and a few other vendors. 
        Definitely avoid them in portable code.

Return to contents page