next up previous contents
Next: Common Extensions to the Up: Professional Programmer's Guide to Previous: Common Blocks

Obsolete and Deprecated Features

None of the features covered here should be used in new software: some of them are completely obsolete, others have practical defects which make them unsuitable for use in well-structured software. These brief descriptions are provided only for the benefit of programmers who have to understand and update programs designed in earlier years.

Storage of Character Strings in Non-character Items

Before the advent of the character data type it was possible to store text in arithmetic variables and arrays, although only very limited manipulation was possible. The number of characters which could be stored in each item was entirely system-dependent. One side-effect is that many systems still allow the A format descriptor to match input/output items of arithmetic types; this sometimes allows mismatches between data-transfer lists and format descriptors to pass undetected.

Arithmetic IF Statement

This is an executable statement with the form:

IF( arithmetic-expression ) label1, label2, label3

It generally provides a three-way branch (but two of the labels may be identical for a two-way branch). The expression may be an integer, real, or double-precision value: control is transferred to the statement attached to label1 if its value is negative, label2 if zero, or label3, if positive.

ASSIGN and assigned GO TO Statements

These two executable statements are normally used together. The ASSIGN statement assigns a statement label value to an integer variable. When this has been done the variable no longer has an arithmetic value. If the label is attached to an executable statement the variable can only be used in an assigned GO TO statement; if attached to a FORMAT statement the variable can only be used in a READ or WRITE statement. The general forms of these statements are:

ASSIGN label TO integer-variable

GO TO integer-variable ,(label, label, ... label)

In the assigned GO TO statement the comma and the entire parenthesised list of labels is optional.

Assigned GO TO can be used to provide a linkage to and from a section of a program unit acting as an internal subroutine, but is not a very convenient or satisfactory way of doing this.

PAUSE Statement

PAUSE is an executable statement which halts the program in such a way that execution can be resumed in some way by the user (or on some systems by the computer operator). The general forms of the statement are identical to those of STOP, for example:

 
       PAUSE 'NOW MOUNT THE NEXT TAPE'
or
 
       PAUSE  54321

PAUSE can be replaced by one WRITE and one READ statement: this is more flexible and less system-dependent.

Alternate RETURN

The alternate RETURN mechanism can be used in subroutines (but not external functions) to arrange a transfer of control to some labelled statement on completion of a CALL statement. In order to use it the arguments of the CALL statement must include a list of labels, each preceded by an asterisk. These labels are attached to points in the calling program unit at which execution may resume after the CALL statement is executed. For example:

 
       CALL BAD(X, Y, Z, *150, *220, *390)

The corresponding subroutine statement will have asterisks as dummy arguments for each label specification:

 
       SUBROUTINE BAD(A, B, C, *, *, *)

The return point depends on the value of an integer expression given in the RETURN statement. Thus:

 
       RETURN 2

will cause execution to be resumed at the statement attached to the second label argument, 220 in this case. If the value of the integer expression in the RETURN statement is not in the range 1 to n (where there are n label arguments) or a plain RETURN statement is executed, then execution resumes at the statement after the CALL in the usual way.

The mechanism can be used for error-handling but is not very flexible as information cannot be passed through more than one procedure level. It is better to use an integer argument to return a status value and use that with an IF (or even a computed GO TO statement) in the calling program.

ENTRY Statement

ENTRY statements can be used to specify additional entry points in external functions and subroutines. ENTRY is a non-executable statement which has the same form as a SUBROUTINE statement. An ENTRY statement may be used at any point in a procedure but all specification statements relating to its dummy arguments must appear in the appropriate place with the other specification statements. If the main entry point is a SUBROUTINE statement than all alternative entry points can be called in the same way as subroutines; if it is a FUNCTION statement than all alternative entry point names can be used as functions. If the main entry point is a character function then all the alternative entry points must also have that type. Alternative entry points may have different lists of dummy arguments; it is up to the user to ensure that all those returning information to the calling program are properly defined before exit.

The rules for the ENTRY statement are necessarily complicated so it is easy to make mistakes. It is generally better, or at least less unsatisfactory, to use a set of separate procedures which share information using common blocks.

EQUIVALENCE Statement

EQUIVALENCE is a specification statement which causes two or more items (variables or arrays) to be associated with each other, i.e. to correspond to the same area of memory. Character items can only be associated with other character items; otherwise the data types do not have to match. As with common blocks, however, transfer of information is only permitted via associated items if their data types match. A special exception is made for a complex item which is associated with two real ones.

EQUIVALENCE statements can be used fairly safely to provide a simple variable name as an alias for a particular array element or to associate a character variable with an array of the same length. For example:

 
       CHARACTER STRING*80, ARRAY(80)*1 
       EQUIVALENCE (STRING, ARRAY)

This slightly simplifies access to a single character in the string as the form ARRAY(K) can be used instead of STRING(K:K).

The general form of the statement is:

EQUIVALENCE ( v, v, ... v ), ( v, v, ... v ), ...

where each v is a variable, array, array element, or substring. Dummy arguments of procedures (and variables which are external function names) cannot appear. An array name without subscripts refers to the first element of the array. It is illegal to associate two or more elements of the same array, directly or indirectly, or do anything which conflicts with the storage sequence rules. Variables and arrays in common blocks can appear in EQUIVALENCE statements but this has the effect of bringing all the associated items into the block. They can be used to extend the contents of the block upwards, subject to the rules for common block length, but not downwards.

Although the EQUIVALENCE statement does have a few legitimate uses it is usually encountered in programs where the rules of Fortran are broken to obtain some special effect. Programs which do this are rarely portable.

Specific Names of Intrinsic Functions

Specific names should be used instead of the generic name of an intrinsic function only if the name is to be the actual argument of a procedure call; the name then must also be declared in an INTRINSIC statement. The following intrinsic functions cannot be used in this way, and their specific names are therefore completely obsolete.


tabular1883
* the functions AMAX0, MAX1, AMIN0, and MIN1 which have a data type different from that of their arguments can only be replaced by appropriate type conversion functions in addition to MAX or MIN.

PRINT Statement and simplified READ

The PRINT statement can produce formatted or list-directed output on the standard pre-connected output file. Thus these two statements have exactly the same effect:

 
       PRINT fmt, data-list 
       WRITE(*, fmt) data-list

The PRINT statement is limited in its functionality and misleading, since there is no necessity for its output to appear in printed form.

In a similar way there is a simplified form of READ statement, so these have the same effect:

 
       READ fmt, data-list 
       READ(*, fmt) data-list

END FILE Statement

The END FILE statement has the same general forms as REWIND and BACKSPACE:

 
       END FILE(UNIT=unit, ERR=label, IOSTAT=int-var) 
       END FILE unit

It appends a special ``end-file" record to a sequential file which is designed to trigger the end-of-file detection mechanism on subsequent input. No further records can be written to the file after this end-file record, i.e. the next operation must be CLOSE, REWIND, or BACKSPACE.

The statement seems to be superfluous on almost all current systems since they can detect the end of an input file without its aid. The Fortran Standard requires that the end-file record be treated as a physical record, so that after an end-of-file condition has been detected an explicit BACKSPACE operation is required before any new data records are appended. This notion is somewhat artificial and not all systems implement it correctly. This is one of the few cases where a deliberate departure from the Fortran Standard can enhance portability.

Obsolete Format Descriptors

The data descriptor Dw.d is exactly equivalent to Ew.d on input; on output it is similar except that the exponent will use the letter D instead of E. Real and double precision data items can be read equally well by D, E, F, or G descriptors.

The format descriptor nHstring is exactly equivalent to 'string' (where n is an unsigned integer constant giving the length of the string). When used with a formatted WRITE statement the string is copied to the output record. The nH form does not require apostrophes to be doubled within the string but does require an accurate character count.


next up previous contents
Next: Common Extensions to the Up: Professional Programmer's Guide to Previous: Common Blocks

Clive Page
Tue Feb 27 11:14:41 GMT 2001