Appendix B. Converting From Fortran 77

A correct, standard-conforming Fortran 77 program is also a correct, standard-conforming Fortran 90 program. However, the Silicon Graphics, Inc. (SGI) implementations of Fortran 77 permit some nonstandard features that are not supported by Fortran 90.

This appendix lists the problems you may encounter when converting some nonstandard Fortran 77 source features to Fortran 90. The following main topics are covered:


Note: This appendix addresses conversion to Fortran 90. You do not need this information when writing new Fortran 90 code. Also, since Fortran 77 object modules can be linked with Fortran 90 object modules, it is always an option to leave all of a program (or specific modules of it) in Fortran 77.



Tip: Refer to “Internet Resources for Fortran 90 Users”; at least one Fortran 77 to Fortran 90 source conversion program is available on the network.


Differences in Source Format

Fortran 77 supports two source formats, 72-column and 120-column. Both forms are accepted by Fortran 90. Specify either the -col72 (or -fixedform) option, or the -col120 option. If you specify neither, Fortran 90 expects any source file with the suffix .f to have the -col72 format. (See “Specifying Source File Format”.)

Fortran 90 supports free-form source input. Specify -freeform to force an input file to be treated as free-form source. Fortran 90 assumes -freeform for input files with the suffix .f90.

Since MIPSpro Fortran 90 supports only 8-bit ASCII characters (see “Character Values and Literals”), there is no question of overflowing the maximum source line length due to nondefault character literals (section 3.3.1 in the MIPSpro Fortran 90 Handbook).

MIPSpro Fortran 90 extends the Fortran 90 standard by accepting up to 99 continuation lines.

No Fortran 77 compiler supports Fortran 90 style free-form source, so do not use it for any module that must be backward-compatible.

Letter Case in Source Files

Letter case is ignored in Fortran source input. SGI Fortran compilers remove the difference between lowercase and uppercase by converting all input text (except for literal character constants) to lowercase before processing it. This is the same in Fortran 90 and Fortran 77.

The only visible result of this policy is that the names of external procedures are always in lowercase when they are recorded in the object file. Other languages, such as C, permit mixed-case input, and therefore can have mixed-case entry-point names in their object files. Mixed-case entry point names cannot be linked with Fortran object files.

Some (not all) SGI Fortran 77 compilers support a compile option -U, specifying that input text should not be forced to lowercase. This has the effect of allowing mixed-case external names to appear in object files. The -U option is not supported by Fortran 90. It is not possible to link directly from a Fortran 90 program to a procedure with a mixed-case name.

Differences in Data Declaration

There are a number of small differences in the syntax of data declaration. Most can be converted by simple text changes.

Differences in Scalar Declarations

In Fortran 77, you can specify the precision of a numeric variable by appending an asterisk and a size to the basic type; for example, REAL*16 or LOGICAL*8.

In Fortran 90, the comparable way of specifying precision is by use of the “kind” parameter in the declaration. However, the SGI implementation of Fortran 90 does permit the use of the asterisk-length notation from Fortran 77. In Example B-1, the declarations in each pair are equivalent.

Example B-1. Syntax of Numeric Precision


INTEGER (KIND=8) eight_byte_int
INTEGER*8 eight_byte_int
REAL (16) quad_real
REAL*16 quad_real


Note: The use of asterisk-length for numeric precision is nonportable, and should not be used in new Fortran 90 code.

Asterisk-length syntax can readily be converted using a tool such as awk or sed. The sed command file in Example B-2 converts asterisk-length declarations to “kind” declarations.

Example B-2. Program to Convert Asterisk Notation


s/INTEGER\*\([248]\)/integer (kind=\1)/
s/LOGICAL\*\([248]\)/logical (kind=\1)/
s/REAL\*\([48]\)/real (kind=\1)/
s/REAL\*16/real (kind=16)/
s/COMPLEX\*8/complex (kind=4)/
s/COMPLEX\*16/complex (kind=8)/
s/COMPLEX\*32/complex (kind=16)/

The use of “kind=” is optional. In programs where the keywords might have different letter cases, the search patterns need to allow for mixed case, as in Example B-3.

Example B-3. Conversion Allowing for Mixed-Case Keywords


 s/[Rr][Ee][Aa][Ll]\*\([48]\)/real(\1)/

Differences in the Syntax of Literals

Literal values are written differently in some cases.

Binary, Octal, and Hexadecimal Literals

Fortran 77 supports a variety of syntax forms when integer literal values are expressed in bases other than decimal. Some of these are supported by Fortran 90 and some are not, as shown in Table B-1.

Table B-1. Forms of Integer Literal Values

Number Base

Example of Form

Supported

2 (binary)

B"00100111"

Yes

8 (octal)

O"33"

Yes

16 (hexadecimal)

X"1B", X"1b"

No

16 (Hexadecimal)

Z"1B", Z'1b'

Yes

16 (Hexadecimal)

$1B

No

Of these forms, the use of prefix dollar-sign for hexadecimal is very common. In Fortran 90, this form causes a syntax error message (“Unexpected symbol”). It is relatively simple to change this form of constant to the supported form using a tool such as sed or perl. For example, the sed command in Example B-4 converts hexadecimal literals.

Example B-4. Conversion of $-Form Literal to “Z” Form


sed 's/\$\([A-F0-9][A-F0-9]*\)/Z"\1"/g'

Conversion of the unsupported “X” form to the “Z” form is equally simple.

Floating-Point Literals

The Fortran 77 syntax for real and double-precision literal values—that is, the use of exponent “E” to mean single-precision and “D” to mean double-precision—is accepted by Fortran 90. Use of these literals is shown in Example B-5.

Example B-5. Syntax for Precision of Floating-Point Literals


real (kind=4) r4
real (kind=8) r8
r4 = 1.665E-2
r8 = 2.468D12

Some SGI Fortran 77 compilers accept the use of exponent-letter “Q” to mean a quad-precision floating-point constant. This usage is also accepted by SGI Fortran 90. In Example B-6, the first assignment uses the Fortran 90 syntax of appending a kind-parameter to the constant, while the second uses the Fortran 77 syntax of an exponent letter of “Q.” The two assignments are effectively the same.

Example B-6. Equivalent Syntax for Quad-Precision Literals


real (kind=16) rp,rq
rp = 1.234567890123456789E7_16
rq = 1.234567890123456789Q7


Note: The “Q” exponent is a nonportable extension of Fortran 90. When writing new programs, write literal values with a _16 suffix. “Q” notation can be converted to standard form using sed, as shown in Example B-7.


Example B-7. Conversion of Q-Exponent Literal to Suffix-16


sed 's/\([.0-9][.0-9]*\)[qQ]\([+-]*[0-9][0-9]*\)/\1e\2_16/g'

Character and Hollerith Literals

The syntax of character literal values is standard Fortran 90. Specific rules are listed under “Character Values and Literals”. There is only one difference from literal syntax in SGI Fortran 77: the backslash is not supported as an escape character. The backslash in a character literal is treated as a character.

Hollerith literals are not defined in the Fortran 90 standard. (Hollerith literals were not part of the Fortran 77 standard, either). However, Hollerith literals can be used with SGI Fortran 77 and Fortran 90. Example B-8 shows the use of a Hollerith literal.

Example B-8. Hollerith Literal Use


integer (8) symbl
symbl = 8Hundefind


Note: Be aware that the use of a Hollerith literal in Fortran 90 is highly nonportable. Hollerith literals may not be supported in future versions of Fortran 90. Whenever possible, convert them to character literals stored in character variables.

The use of the Hollerith edit descriptor in a FORMAT statement is a separate issue. The Hollerith edit descriptor (nH) for FORMAT is defined in the Fortran 90 standard as an obsolescent feature. The compiler issues a warning when it processes a FORMAT statement containing a Hollerith edit code. In contrast, the use of a Hollerith literal in an expression is not defined in the standard at all, and the current compiler processes it without a message.

Differences in Pointer Data

SGI Fortran 77 supports the POINTER statement as a way of declaring two associated names: a name for a pointer, and a name for the variable addressed by the pointer. Whenever the program refers to the addressed variable, the compiler inserts code to load the variable's address from the associated pointer variable.

Only the pointer variable is defined as part of the program image. It can be treated as an integer in expressions. It is usually assigned a value (an integer that represents a memory address) from one of two sources:

  • a value returned by the malloc() system function, pointing to a dynamic allocation of memory

  • an address returned by the LOC% function, pointing to another Fortran variable

Fortran 90 supports dynamic allocation and pointer-based variables, but the syntax for these features is completely different from that of Fortran 77. One fundamental difference is that, in Fortran 90, there is only one name for an pointer-based variable. This name normally stands for the addressed variable. In the context of a special pointer-assignment statement, the name stands for the pointer that addresses the variable.

There is no straightforward, source-level change you can make to convert a program using POINTER statements to Fortran 90. One reason is that the POINTER mechanism is used for two or more distinct purposes. In order to convert a program, you must determine why it uses POINTER.

  • Often the reason is simply to permit dynamic memory allocation and reallocation of variables. In this case, you can rewrite the code to use Fortran 90 allocatable variables. Pointers are not necessary; the compiler generates code to allocate memory automatically.

    For details on allocatable variables, see the Fortran 90 Handbook, sections 5.3.3 and 6.5.1.

  • When the reason is to permit general addressing, in which one name refers to different data objects at different times—for example, to navigate through a binary tree or similar dynamic structure—then you can rewrite the code to use the Fortran 90 POINTER data attribute and pointer assignment.

    For details on pointers in Fortran 90, see the Fortran 90 Handbook, sections 5.4 and 7.5.3.

Occasionally the reason for POINTER use is to manipulate or interrogate general memory addresses, or to do hardware-dependent system programming. Such programs are best left in Fortran 77.

Differences in Declaration of Structures

SGI Fortran 77 compilers accepted the nonstandard STRUCTURE, UNION, and RECORD statements as a way of declaring structures composed of heterogenous data fields. These statements are not supported by Fortran 90. Most of the same purposes are served using Fortran 90 derived types.

Basic Structure Declarations

Example B-9 shows a typical structure declaration and its use in Fortran 77.

Example B-9. Fortran 77 Program Using a Structure


      structure /weather/
         integer*1 month /08/, day /10/, year /89/
         character*20 clouds
         real rainfall
      end structure
      record /weather/ latest
      latest.clouds = 'overcast'
      latest.rainfall = 3.12
      print *, latest.clouds, latest.rainfall
      end

A comparable Fortran 90 program is shown in Example B-10.

Example B-10. Fortran 90 Program Using a Structure


type weather
   integer (1) :: month = 04, day = 18, year = 95
   character (20) clouds
   real rainfall
end type weather
type (weather) latest
latest = weather(04,18,95,'overcast',3.12)
print *, latest%clouds, latest%rainfall
end

The programs are fundamentally alike. Each declares a structure composed of named fields, then defines and initializes a variable holding one instance of the structure, and finally accesses the fields of the variable.

Compare Example B-9 and Example B-10 and note the following syntactic differences:

  • The Fortran 90 structure opens with TYPE name instead of STRUCTURE /name/.

  • The structure closes with END TYPE name instead of END STRUCTURE.

  • The Fortran 90 syntax for initial field values is assignment with the equals sign (the same syntax is used to give initial values to any variable). The Fortran 77 syntax for initial field values is similar to the DATA statement.

  • The Fortran 90 definition of a structure variable opens with TYPE (name) instead of RECORD /name/.

  • Fortran 90 supports the use of a structure constructor to allow assigning all fields of a structure in one statement.

  • In Fortran 90, you access a field using structure%field instead of using structure.field.

The syntactic differences could be converted using a tool such as awk or perl.

Equivalenced and Common Structures

There is an important semantic difference between Fortran 77 structures and Fortran 90 structures. In Fortran 77, fields within a structure are always placed in memory in the order they are declared. This is not necessarily true in Fortran 90. By default, the compiler can choose to reorder the fields in memory.

If you use the EQUIVALENCE or COMMON statement in order to set up a storage association between the fields of a structure and other data, you must specify the SEQUENCE statement within the structure declaration. This forces the compiler to keep the fields in their declared order, in memory.

Unions

SGI Fortran 77 compilers support the UNION statement as a way of declaring multiple data types for fields within a structure. The declaration in Example B-11 allows a field to be treated as either a COMPLEX or a pair of REAL values.

Example B-11. Fortran 77 UNION Declaration


      structure /cxre/
         union
            map
               complex cx
            end map
            map
               real re, im
            end map
         end union
      end structure

The UNION statement is not supported by Fortran 90. If it is essential to treat a field under different types at different times, you can set up a storage association through the EQUIVALENCE statement.

Differences in Intrinsic Procedures

There are differences in the intrinsic procedures available in SGI Fortran 77 and in Fortran 90. The latter supports fewer specific intrinsic functions and some Fortran 77 extended intrinsics need to be converted.

Differences in Intrinsic Functions

Both Fortran 77 and Fortran 90 support a set of intrinsic functions. Both languages distinguish between generic functions and specific functions. A generic function accept various data types as input. A specific function requires arguments of specific types. In fact, the compiler converts a call on a generic function into a call on the specific function that is appropriate for the type of argument.

In general, Fortran 90 provides a broader range of generic functions, but supports fewer specific intrinsic functions than SGI Fortran 77. The Fortran 90 standard deliberately defines few specific names.

Where a Fortran 77 program uses generic functions, no conversion is needed. Where it uses specific functions by name, it may need to be changed.

Specific Intrinsic Functions for Data Type Conversion

SGI Fortran 77 has a large number of specific functions for data type conversion. For example, the generic function INT returns the integer value of its argument. However, there are also specific functions based on the type of argument and the type of result required, for example JINT, KINT, IIDINT, KIDINT, IIQINT, and so on.

Fortran 90 supports only the generic names for conversion functions, such as INT, REAL, and CMPLX. However, each of these accepts an optional second argument that specifies the desired result type.

For example, the Fortran 77 function IIQINT(r), which converts REAL(16) to INTEGER(2), can be replaced by INT(r,KIND=2). The function QCMPLX(r,i), which converts to quad-complex, can be replaced by CMPLX(r,i,KIND=16).

Calls to the specific data conversion functions of Fortran 77 must be converted in this way, using generic functions with KIND parameters as needed.

Specific Intrinsic Functions for Transcendentals

SGI Fortran 77 supports a number of specific intrinsic names that are used to apply transcendental functions on arguments of particular data types. For example, the CQSIN function returns the sine of a quad-precision complex number.

Fortran 90 supports the generic SIN function and only two specific names, CSIN (complex) and DSIN (double precision). When you find one of the unsupported specific names used, you must determine why it was used.

  • If it was used only to be specific about the data type of the argument or result, replace it with the generic name.

  • If it is being passed as an argument to another function, you must either leave the module in Fortran 77, or supply a Fortran 90 function of the same name that performs that function.

Degree-Oriented Trigonometric Functions

SGI Fortran 77 supports a set of intrinsic functions to do trigonometric functions in degree values instead of radian values; for example, DCOSD returns the cosine as a double-precision value in degrees.

Fortran 90 does not supply these degree-oriented functions. If you find one used, you must convert the program from using an intrinsic to using an external function that does the same operation. Degree-oriented functions may be found at some Internet sites (see “Internet Resources for Fortran 90 Users”). Example B-12 displays a skeleton for a MODULE of functions.

Example B-12. Skeleton of a Module of Trigonometric Functions


module degree_trig
   real(16), parameter :: &
      quadpi = 3.141592653589793238462643383279502884197Q0
   real(16), parameter :: dgr_to_rad = (quadpi/180Q0)
   intrinsic cos, sin, tan
contains
   function sind(dgr_argument)
   real(4) sind, dgr_argument
      sind = sin(dgr_to_rad * dgr_argument)
   end function

   function cosd(dgr_argument)
   real(4) cosd, dgr_argument
      cosd = cos(dgr_to_rad * dgr_argument)
   end function

   function tand(dgr_argument)
   real(4) tand, dgr_argument
      tand = tan(dgr_to_rad * dgr_argument)
   end function

   function dsind(dgr_argument)
   real(8) dsind, dgr_argument
      dsind = sin(dgr_to_rad * dgr_argument)
   end function

   function dcosd(dgr_argument)
   real(8) dcosd, dgr_argument
      dcosd = cos(dgr_to_rad * dgr_argument)
   end function

   function dtand(dgr_argument)
   real(8) dtand, dgr_argument
      dtand = tan(dgr_to_rad * dgr_argument)
   end function
end ! module


Tip: Some programmers find it a pleasant exercise to write their own version of CQSIN or DCOSD, but you can save time by using a version that is already written. Refer to “Internet Resources for Fortran 90 Users” for pointers to available, public-domain software libraries.


Converting Extended Intrinsic Procedures

SGI Fortran 77 supports several nonstandard intrinsic subroutines and functions. In Fortran 90, the purposes of most of these procedures are served by standard intrinsic procedures. The correspondence is summarized in Table B-2.

Table B-2. Corresponding Intrinsic Procedures

Fortran 77 Intrinsic Name

Fortran 90 Intrinsic Name

DATE

DATE_AND_TIME

ERRSNS

None, see “Converting Calls to ERRSNS”

EXIT

STOP statement; also see “Converting Calls to EXIT”

IDATE

DATE_AND_TIME

MVBITS

MVBITS (same function, now standard)

RAN

RANDOM_NUMBER and RANDOM_SEED


Converting Calls to ERRSNS

The ERRSNS subroutine returns the last I/O error code and the associated unit number. There is no direct conversion for this function. The last error code alone can be retrieved in either of two ways:

  • The ierrno() function (see the perror(3f) reference page) returns the most recent error code from any operation.

  • The INQUIRE statement with an IOSTAT= clause returns the error code associated with a specified unit or file.

However, if the program depends on the ability to recall the unit number along with the error code, you must revise its logic.

Converting Calls to EXIT

The EXIT function terminates execution. So does the STOP statement. The difference between them is that CALL EXIT allows you to end the program with a negative integer return code. STOP accepts only positive integers or character strings.

There is no direct conversion for EXIT. However, a C function like the one shown in Example B-13 can serve the same purpose.

Example B-13. Substitute for EXIT


extern void
exit_ (int *exitstatus)
{
   f_exit();
   exit(exitstatus ? (int)*exitstatus : 0);
}

Converting Calls to RAN

The Fortran 77 subroutine RAN performs two purposes: it accepts a seed value, and it returns an updated seed value which is also a pseudorandom number. Fortran 90 separates these two purposes. You call RANDOM_SEED to save, or to restart, a sequence of pseudorandom numbers. You call RANDOM_NUMBER to retrieve one or more new values from the current sequence. When porting a Fortran 77 program that uses RAN, analyze the program logic to find the point, or points, at which it changes the seed value. Convert these to calls on RANDOM_SEED.

The algorithm used by RANDOM_NUMBER is more robust than the one used by RAN (see “Implementation of RANDOM_NUMBER”).

Differences in I/O Processing

The Fortran 77 run-time library supports several I/O features that are not part of Fortran 90. The features are summarized, with possible work-around schemes, in the topics that follow. In Table B-3 is a list of Fortran 77 keywords that indicate use of an unsupported I/O feature. When you find one of these words in a Fortran 77 program, use the table to find the discussion of the feature.

Table B-3. Keywords Indicating Use of Unsupported Features

Keyword or Statement Name

Feature and Topic Reference

name .EQ. "UNKNOWN"

“UNDEFINED Instead of UNKNOWN”

-vms_endfile (compiler option)

“VMS Endfile”

ACCEPT

“ACCEPT Statement”

ACCESS="APPEND"

“Open File for APPEND”

ACCESS="KEYED"

“Key-Indexed (ISAM) Access”

ASSOCIATEVARIABLE=var

“Getting the Number of the Next Record”

CARRIAGECONTROL=type

“Carriage Control”

DECODE

“Internal Files in Numeric Arrays”

DEFAULTFILE=fname

“Default Filename Prefix”

DEFINE FILE

“Open Direct File With DEFINE”

DELETE [UNIT=]unit

“Key-Indexed (ISAM) Access”

DISP[OSE]=disposition

“File Disposition”

ENCODE

“Internal Files in Numeric Arrays”

FIND ([UNIT=]unit...)

“Seeking a Position With FIND”

NML=groupname

“Namelist Data Compatibility”

OPEN...FILE=numeric_var

“Numeric Variable for FILE”

OPEN...FORM="BINARY"

“Special File Formats”

OPEN...FORM="SYSTEM"

“Special File Formats”

OPEN...KEY=(...)

“Key-Indexed (ISAM) Access”

OPEN...MAXREC=n

“Maximum Records in a Direct File”

OPEN...READONLY

“Enforcing Read-Only Access”

OPEN...RECORDSIZE=n

“RECORDSIZE Instead of RECL”

OPEN...SHARED

“SYNC Mode Output”

OPEN...TYPE=statusvar

“OPEN TYPE Instead of OPEN STATUS”

ORGANIZATION=

“Key-Indexed (ISAM) Access”

READ...KEY=key

“Key-Indexed (ISAM) Access”

RECORDTYPE=rectype

“Specifying the Record Type”

REWRITE

“Key-Indexed (ISAM) Access”

TYPE fmt,iolist

“TYPE Synonym for PRINT”

UNLOCK

“Key-Indexed (ISAM) Access”


ACCEPT Statement

The ACCEPT statement in Fortran 77 transfers data from the standard input unit to the items specified by the input list. Replace it in Fortran 90 with a READ from unit 5.

Carriage Control

(This topic amplifies the Fortran 90 Handbook topic 9.2.10.)

Carriage control is not supported in Fortran 90. Formatted output always starts in column 1, and list-directed output always starts in column 2, leaving a space character in column 1.

The Fortran 77 CARRIAGECONTROL clause can be used with OPEN to specify the type of carriage control to be used with the file. It can be specified with INQUIRE to find out the type of carriage control used by a file.

Since the clause is not supported, remove it from the OPEN statement. If the value specified was NONE and this file uses only formatted output, or if value specified was LIST and this file uses only list-directed output, no further conversion is needed—the Fortran 90 output will be the same as in Fortran 77.

Otherwise, you have to determine if the column-1 carriage control characters are really required by the programs that use the output. If so, you have to modify the WRITE and FORMAT statements used for output so as to generate the needed column-1 data.

If the CARRIAGECONTROL clause appears on an INQUIRE statement, remove it and replace it with an assignment of "UNKNOWN" to the variable.

Default Filename Prefix

The DEFAULTFILE clause of Fortran 77 OPEN establishes a prefix string that is used with the FILE clause to construct the full name of the file to be opened. When STATUS="SCRATCH"is specified, the prefix string is used with the UNIT number to construct a name for the temporary file.

The DEFAULTFILE clause can also be used with INQUIRE to retrieve the value given at OPEN.

This feature is not supported by Fortran 90. You have to revise the program to construct the filename string using character expressions, and pass the full string in the FILE clause. Store the prefix string in a global variable. If the clause appears on an INQUIRE statement, replace it with an assignment from the global variable.

Enforcing Read-Only Access

In Fortran 77, you specify that a file is to be read-only by writing the READONLY clause in the OPEN statement.

The same purpose in Fortran 90 is achieved by writing ACCESS=READ in the OPEN statement. This is a simple textual change.

File Disposition

Fortran 77 supports the use of the DISPOSE=disposition clause on the OPEN statement. It also allows the use of DISPOSE=disposition clause on a CLOSE statement to override the disposition of the file.

This clause is not supported by Fortran 90. The possible dispositions and their conversions are as follows.

KEEP, SAVE

Default disposition. Simply comment-out the clause.

PRINT

Arrange for printing in some other way, for example by calling the system() library function with an lp command specifying the filename.

SUBMIT

Arrange for execution in some other way, for example by calling the system() library function with a command string that pipes the file to sh.

PRINT/DELETE, SUBMIT/DELETE

Not supported. Handle PRINT or SUBMIT as above, and use the unlink() system function to delete the file.

For more on system functions, see “Support for IRIX Kernel Functions”. For details on the Fortran 90 OPEN statement, see the Fortran 90 Handbook section 9.5.

Getting the Number of the Next Record

When using direct access, the program sometimes needs to know the record number at which the file is currently positioned. In Fortran 77 and in Fortran 90, you can get this information with the INQUIRE NEXTREC= clause.

In Fortran 77 you can use OPEN ASSOCIATEVARIABLE= to specify a variable that is automatically updated with the next record number after every access to the file. This feature is not supported in Fortran 90. You have to delete the clause from OPEN, and ensure that the specified variable is updated by INQUIRE before it is used.

Internal Files in Numeric Arrays

Fortran 77 permits storing internal files in numeric arrays, rather than in character variables as is normal for internal files. This is done using the DECODE and ENCODE statements instead of READ and WRITE.

This feature is not supported in Fortran 90. Recode the program to use READ and WRITE (the statement parameters are almost the same) and character variables.

Key-Indexed (ISAM) Access

SGI Fortran 77 supports key-indexed access to files. Key-index access is also called indexed-sequential access, or ISAM. The sign that a file is used in this way is the appearance of ACCESS="KEYED" in the OPEN statement.

Key-indexed access is not supported by Fortran 90. If this type of access is essential to the application, it is probably best to not attempt a conversion to Fortran 90.

The DELETE statement is used only with key-indexed files. It deletes the record last retrieved.

The following clauses of the INQUIRE statement are related to key-indexed access and need to be changed:

ACCESS=

Cannot return the value "KEYED"

KEYED=

Not supported, must be removed

ORGANIZATION=

Not supported, must be removed (ACCESS= returns comparable information for the supported access modes)


Maximum Records in a Direct File

The Fortran 77 OPEN statement accepts the MAXREC= clause to specify the maximum number of records in a direct-access file. This clause is not supported by Fortran 90. Remove the clause. If the program relies on the Fortran run-time library to detect creation of a record beyond the maximum size, you have to revise the program to enforce the limit using program logic.

Namelist Data Compatibility

The form of a namelist data record as supported by MIPSpro Fortran 77 is:

{ $ | &}groupname   item = value [,...] [/] {$ | &}[END]

In particular, the “/” terminator is used only when input is to terminate early, and is never written by a namelist WRITE statement. Even when “/” is present, the record must be terminated by a “$” or “&” after it.

The form of a namelist data record as defined for Fortran 90 is:

&groupname   item = value [,...] /

That is, the “/” terminator is required on all records; is always written; and no terminating “&” is required. These two formats are not compatible, so namelist data files prepared by or for a Fortran 77application are formally incompatible with a Fortran 90 application.

Two extensions are supported in MIPSpro Fortran 90 to relieve this incompatibility. An input namelist is allowed to start with either “&” or “$” (recognition of “$” is an extension). An input namelist is allowed to end with “/” or “$,” and characters between “$” and end of record are ignored (recognition of “$” is an extension).

These extensions permit Fortran 90 to read namelist data prepared by a Fortran 77 program. This allows you to convert a Fortran 77 program to Fortran 90 and still read the data that was written by the Fortran 77 version. A Fortran 77 program cannot read namelist data written by Fortran 90.


Note: Fortran 90 cannot read namelist data written by Fortran 90 when the output contains CHARACTER data, unless the output was written with delimiters (not the default behavior). This is the standard-defined behavior.


Numeric Variable for FILE

SGI Fortran 77 permits the use of a numeric variable as the operand of the FILE= clause of the OPEN statement. (Such a numeric variable might be initialized using a Hollerith literal; see “Character and Hollerith Literals”.)

The Fortran 90 standard specifies that the FILE= clause must specify a character expression.

Open Direct File With DEFINE

The DEFINE FILE statement is effectively the same as the OPEN statement with the ACCESS="DIRECT" clause. Rewrite the DEFINE FILE to use OPEN instead.

Open File for APPEND

In Fortran 77 you use the OPEN clause ACCESS="APPEND" to open a file for output at end. To do the same thing in Fortran 90, change

OPEN (...ACCESS="APPEND"...)

to read

OPEN (...ACCESS="SEQUENTIAL",POSITION="APPEND"...)

For details on the OPEN statement, refer to the Fortran 90 Handbook topic 9.6.

OPEN TYPE Instead of OPEN STATUS

The Fortran 77 OPEN statement permits the clause TYPE= as a synonym for the STATUS= clause. For Fortran 90 use, rewrite TYPE= as STATUS=.

RECORDSIZE Instead of RECL

Fortran 77 permits the RECORDSIZE= clause of OPEN as a synonym for the RECL= clause. Change the word RECORDSIZE to RECL for Fortran 90.

Seeking a Position With FIND

The Fortran 77 FIND statement sets the record position of a direct-access file without transferring any data. It is not supported by Fortran 90. You can achieve the same result using an unformatted, direct-access READ with an empty iolist.

Special File Formats

In SGI Fortran 77, the FORMAT clause of OPEN can specify two special modes:

  • FORMAT="BINARY" permits reading and writing binary data from character variables.

  • FORMAT="SYSTEM" allows input ignoring record boundaries.

These special modes are permitted by MIPSpro Fortran 90. However, neither is supported by the Fortran 90 standard. Either type of file access can also be achieved by using the IRIX kernel functions read() and write() (see “Support for IRIX Kernel Functions”).

Specifying the Record Type

Fortran 77 accepts the RECORDTYPE= clause on the OPEN and INQUIRE statements. On OPEN, the only acceptable value is the default type for the file based on the ACCESS and FORMAT clauses. The record type is returned on INQUIRE.

The RECORDTYPE= clause is not supported by Fortran 90. The run-time support expects the same default record types as Fortran 77 (files are interchangeable between languages). Comment-out the clause on the OPEN statement. If the clause appears on the INQUIRE statement, replace it with an assignment of a constant string to the target variable.

SYNC Mode Output

The Fortran 77 OPEN statement permits the clause SHARED to request that the file be written to disk as soon as possible. This clause is not supported by the Fortran 90 standard.

You can remove the SHARED clause but get the same support using the fcntl() library function (see “Support for IRIX Kernel Functions”) to set the F_SYNC file descriptor flag.

TYPE Synonym for PRINT

In SGI Fortran 77, you can use the word TYPE as a synonym for the word PRINT. This is not possibly in Fortran 90, where TYPE is the statement used to declare a structure (see “Differences in Declaration of Structures”). Replace TYPE with PRINT.

UNDEFINED Instead of UNKNOWN

Certain clauses of the Fortran 90 INQUIRE statement return the string UNDEFINED in situations where Fortran 77 returned the string UNKNOWN. This is true of the ACCESS, BLANK, and FORM queries (as well as DELIM and POSITION, which will not appear in a Fortran 77 program).

If the Fortran 77 program inquires these values and then compares .EQ. "UNKNOWN," it will always get a result of .FALSE.

Other INQUIRE clauses do return UNKNOWN as in Fortran 77: DIRECT, FORMATTED, SEQUENTIAL, and UNFORMATTED.

VMS Endfile

Normally the end of a sequential file is defined by the IRIX file-size information. All data in the file is part of the file. Under Fortran 77 you can pass the -vms_endfile option to the compiler. This causes the run-time code for formatted input to recognize a control-D character in the input stream as an end of file mark.

Fortran 90 does not support this option. You can write a program in C or perl to read a file and truncate it (using the system function ftruncate() or the perl function truncate()) at the length preceding the first control-D. You can write a Fortran 90 program to read a file and copy it, stopping the copy at the first control-D (Fortran 90 does not have access to the ftruncate() system function). Either of these methods can be used to clean up a file that uses the VMS endfile convention, so that it can be read using Fortran 90 conventions.