HP 3000 Computer Systems HP FORTRAN 77/iX Programmer's Guide ABCDE HP Part No. 31501-90011 Printed in U.S.A.
The information contained in this document is subject to change without notice. HEWLETT-PACKARD MAKES NO WARRANTY OF ANY KIND WITH REGARD TO THIS MATERIAL, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Hewlett-Packard shall not be liable for errors contained herein or use of this material. Hewlett-Packard assumes no responsibility for the use or reliability of its software on equipment that is not furnished by Hewlett-Packard.
Printing History The following table lists the printings of this document, together with the respective release dates for each edition. The software version indicates the version of the software product at the time this document was issued. Many product releases do not require changes to the document. Therefore, do not expect a one-to-one correspondence between product releases and document editions.
Preface Chapter Summary iv This is the reference manual for the HP FORTRAN 77 programming language as it is implemented on the MPE/iX operating system. This manual assumes that the reader has been trained in the FORTRAN language and knows FORTRAN programming techniques. This manual is organized into the following chapters: chapter 1 Describes the factors that in uence storage allocation for a FORTRAN variable. chapter 2 Describes how to use formatted and list-directed input/output statements.
Additional Documentation More information on HP FORTRAN 77 and related topics can be found in the following manuals: HP FORTRAN 77/iX Reference (31501-90010) This manual is a complete reference of all HP FORTRAN 77/iX features. HP FORTRAN 77/iX Migration Guide (31501-90004) This manual contains information on how to run FORTRAN 66/V and HP FORTRAN 77/V programs on the MPE/iX operating system and how to convert them to HP FORTRAN 77/iX programs.
Conventions UPPERCASE In a syntax statement, commands and keywords are shown in uppercase characters. The characters must be entered in the order shown; however, you can enter the characters in either uppercase or lowercase.
{ In a syntax statement, braces enclose required elements. When several elements are stacked within braces, you must select one. In the following example, you must select either ON or OFF: } COMMAND [ ON OFF In a syntax statement, brackets enclose optional elements. In the following example, OPTION can be omitted: ] COMMAND lename [OPTION] When several elements are stacked within brackets, you can select one or none of the elements.
Conventions | . .. | (continued) In a syntax statement, horizontal ellipses enclosed in vertical bars indicate that you can select more than one element within the immediately preceding pair of brackets or braces. However, each particular element can only be selected once. In the following example, you must select A, AB, BA, or B. The elements cannot be repeated. ... A | B ... | In an example, horizontal or vertical ellipses indicate where portions of an example have been omitted.
Contents 1. Data Storage Variable Type . . . . . . . . . . . . . . . . . Addressing Mode . . . . . . . . . . . . . . . . The EQUIVALENCE Statement . . . . . . . . . Equivalence of Array Elements . . . . . . . . . Equivalence and Multi-Dimensioned Arrays . . . Equivalence Between Arrays of Di erent Dimensions Equivalence of Character Variables . . . . . . . Equivalence in Common Blocks . . . . . . . . Equivalence and Data Alignment . . . . . . . . HP FORTRAN 77/iX Storage Assignment . . . . . Memory Areas .
The Output Field . . . . . . . . . . . . . Repeating Speci cations . . . . . . . . . . . . Correspondence Between the I/O List and Format Descriptors . . . . . . . . . . . . . . . . Monetary Format Descriptor: M . . . . . . . . The Input Field . . . . . . . . . . . . . . The Output Field . . . . . . . . . . . . . Numeration Format Descriptor: N . . . . . . . The Input Field . . . . . . . . . . . . . . The Output Field . . . . . . . . . . . . . Processing New Lines . . . . . . . . . . . . .
Unformatted Output . . . . . . . . . . . . Using Formatted and Unformatted Files . . . . . Using the INQUIRE Statement . . . . . . . . Positioning the File Pointer . . . . . . . . . . The BACKSPACE Statement . . . . . . . . The REWIND Statement . . . . . . . . . . The ENDFILE Statement . . . . . . . . . . Example of Using the File Positioning Statements File Handling Examples . . . . . . . . . . . . Computing the Mean of Data in a Sequential File Inserting Data Into a Sorted Sequential File . .
5. Subprograms Subroutines . . . . . . . . . . . . . . . . . Structure of a Subroutine . . . . . . . . . . Invoking Subroutines . . . . . . . . . . . . Alternate Returns From Subroutines . . . . . Functions . . . . . . . . . . . . . . . . . . Function Subprograms . . . . . . . . . . . Statement Functions . . . . . . . . . . . . Arguments to Subprograms . . . . . . . . . . Passing Constants . . . . . . . . . . . . . Passing Expressions . . . . . . . . . . . . . Passing Character Data . . . . . . . . . . .
Grouping Related Routines . . . . . . . . . . . Shifting Data from the Data Area to the Stack Area Integer Over ow Checking . . . . . . . . . . . . Using the Optimizer . . . . . . . . . . . . . . Introduction to the Optimizer . . . . . . . . . When to Use the Optimizer . . . . . . . . . . Invoking the Optimizer on MPE/iX . . . . . . . Level One Optimization Modules . . . . . . . . Branch Optimization Module . . . . . . . . Dead Code Elimination Module . . . . . . . Faster Register Allocation Module . . . .
Resolving Incompatibilities between MPE V and MPE/iX: the HP3000 16 . . . . . . . . . . . The ON Option . . . . . . . . . . . . . . . The OFF Option . . . . . . . . . . . . . . . The ALIGNMENT Option . . . . . . . . . . The REALS Option . . . . . . . . . . . . . The STRING MOVE Option . . . . . . . . . 8. Interfacing with Other Languages HP Pascal/iX . . . . . . . . . . . . . . . . . Calling HP Pascal/iX from HP FORTRAN 77/iX Calling HP FORTRAN 77/iX from HP Pascal/iX HP COBOL II/iX . . . . . . . . . . . .
Removing Debugging Information . . . . . Using HP Toolset/iX . . . . . . . . . . . . Compiling Programs for HP Toolset/iX . . . Invoking HP Toolset/iX . . . . . . . . . . Setting Up for Symbolic Debug . . . . . . . When to Use HP Toolset/iX . . . . . . . . Running a Program . . . . . . . . . . . . Setting Breakpoints . . . . . . . . . . . . Tracing Names . . . . . . . . . . . . . . Clearing Breakpoints . . . . . . . . . . . Displaying Variables . . . . . . . . . . . Modifying Variables . . . . . . . . . . .
Figures 2-1. 2-2. 2-3. 3-1. 3-2. 3-3. 7-1. 7-2. 7-3. The Aw Format Descriptor . . . . The Rw Format Descriptor . . . . The Aw and Rw Format Descriptors Sequential Access Files . . . . . . Direct Access Files . . . . . . . . Indexed Sequential Access Files . . MPE V Structure . . . . . . . . MPE/iX Structure . . . . . . . . Shifted MPE/iX Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-1. 1-2. 1-3. 1-4. 2-1. 2-2. 3-1.
1 Data Storage The data allocation for a FORTRAN variable is in uenced by three factors: Variable type Addressing mode The EQUIVALENCE statement This chapter describes these factors in detail.
Variable Type The variable data types of FORTRAN 77 and their corresponding assignment statements are shown in Table 1-1. Table 1-1.
Addressing Mode The FORTRAN compiler generates machine instructions that access program data. Depending on the type of the data, the instructions use any of the modes of addressing shown in Table 1-2. Table 1-2. Addressing Mode Addressing Mode Description Direct Accesses data directly by using the address given to the variable. Accesses data by using a pointer to the address of the data. Accesses data by using a record containing the address of the data and the maximum length.
The EQUIVALENCE Statement Equivalence of Array Elements Storage space is allocated in memory consecutively; every variable is independent. Except for common variables, the declaration order of variables in the source code does not determine the order in which the variables are allocated in memory. However, this pattern of allocation can be changed with the EQUIVALENCE statement, which allows overlapping of the same storage space with more than one variable.
By using the EQUIVALENCE statement, array elements can share the same storage space. If the arrays are not of the same type, they might not line up element-by-element.
Equivalence and Multi-Dimensioned Arrays As an extension to the ANSI standard, you can indicate on an EQUIVALENCE statement the element of a multi-dimensioned array by specifying its position in the array.
Equivalence Between Arrays of Different Dimensions To determine equivalence between arrays with di erent dimensions, FORTRAN contains an internal array successor function that views all elements of an array in linear sequence. Each array is stored as if it were a one-dimensional array. Array elements are stored in ascending sequential column-major order. The rst index varies the fastest, then the second, and so on.
Equivalence of Character Variables As an extension to the ANSI 77 Standard, character and noncharacter data items can share the same storage space. For example, the statements: INTEGER*4 i(5) CHARACTER*16 c EQUIVALENCE(i,c) produce the following storage space allocation: Array i Storage Space Byte Number Variable c i(1) 1 - 4 c(1:4) i(2) 5 - 8 c(5:8) i(3) 9 - 12 c(9:12) i(4) 13 - 16 c(13:16) i(5) 17 - 20 The lengths of the data items that share the same storage space do not have to match.
Equivalence in Common Blocks Data elements can be put into a common block by specifying the elements as equivalent to data elements mentioned in a COMMON statement. If one element of an array shares the same storage space with a data element in a common block by using the EQUIVALENCE statement, the whole array is placed in the common block. Equivalence is maintained for the storage unit preceding and following the data element in common.
Equivalence and Data Alignment Each data type has its own data alignment requirement that is system dependent; see the HP FORTRAN 77/iX Reference for details. If you force any variable to start on a boundary other than the alignment required, a compilation error occurs.
HP FORTRAN 77/iX Storage Assignment Memory Areas This section describes the 900 Series HP 3000 computer hardware architecture as it relates to the placement of FORTRAN 77 data objects. This section also describes the actions of the compiler to assign data areas to FORTRAN 77 variables and common blocks. Refer to the HP FORTRAN 77/iX Reference for information on data formats of the FORTRAN 77 data types.
Memory Area Assignment Note This section describes how variables and common blocks are assigned to the memory areas. The location eld from the TABLES ON compiler directive lists each data object's assigned memory area. Use this directive if there is any doubt about the location of a data object. Local Variables Uninitialized local variables are normally assigned to the stack area. Variables that are initialized with a DATA statement, such as DATA var /3.2/ are assigned to the data area.
Summary of the Memory Area Assignment Table 1-4 summarizes the assignment rules of the memory areas. Table 1-4.
2 Formatted Input/Output HP FORTRAN 77 provides you with control over I/O operations through the use of format speci cations. Formatted I/O can be used for I/O access to devices (such as terminals), line printers, or disk les. This chapter describes how to use formatted I/O and list-directed (free-format) I/O. Chapter 3 describes how to use unformatted I/O and nonstandard les.
The input eld can be terminated abruptly by entering a slash ( / ) in the input eld, causing any remaining items in the I/O list to be skipped. For example, if the input line: 5 / is read by one of these statements: READ(5,*) i, j, k READ *, i, j, k the variable i is assigned the value 5, and the read terminates. The variables j and k are unchanged. Entering a slash is useful when you want to enter only the rst few values of a long input list.
List-Directed Output A list-directed output statement can be written in one of two ways. First, the WRITE statement must have a unit number for the destination of the output data. For example, WRITE(6,*) 'Output values=', i, j, k Second, the PRINT statement always writes to the standard output device. For example, PRINT *, 'Output values=', i, j, k There is no WRITE statement equivalent to the PRINT statement form.
Following is another program with list-directed output statements: PROGRAM output_ex COMPLEX vector CHARACTER string*8 vector = (1.0, 1.0) string = 'alphabet' int = 123 var = 123.456E29 PRINT *, vector, string, int, var END The output of this program is the following line: (1.0,1.0)alphabet 123 1.23455E+31 Note that blanks are inserted before numeric values and not before character strings. List-directed I/O can also be done on nonstandard les, as described in Chapter 3.
Formatted Statements Formatted I/O statements use format descriptors that supplement the READ, WRITE, or PRINT statements to exactly de ne the format of the data. The descriptors can be speci ed on the READ, WRITE, or PRINT statements, or can appear in a FORMAT statement. The FORMAT statement is a nonexecutable statement that describes how the data listed in a READ, WRITE, or PRINT statement is to be arranged.
Formatted Input The formatted READ statement transfers data from an external device to internal storage, and converts the ASCII data to internal representation according to the format descriptor. One way of specifying a formatted READ statement is to place the descriptors on the READ statement itself. For example, the statement: READ (5, '(I5, F5.1)') int, value reads data from unit 5 into int and value according to the format descriptors I5 and F5.1, respectively.
Formatted Output The formatted WRITE and PRINT statements transfer data from the storage location of the variables or expressions named in the output list to the le associated with the speci ed unit. The data is converted to a string of ASCII characters according to the format descriptors. One way of specifying a formatted WRITE statement is to include the format descriptors on the WRITE statement itself. For example, the statement: WRITE (6, '(1X, I5, F3.
Variable Format Descriptors Variable format descriptors allow the values of integer variables, integer constants, and character constants to be imported into format strings. Integer variable format descriptors may be used wherever an integer may appear, except to specify the number of characters in a Hollerith eld. To use a variable format descriptor, enclose the variable or constant in angle brackets.
The output of of the program is as follows: 1 2 3 1.0 2.0 5.0 3.0 6.0 9.
Summary of the Descriptors The format descriptors, which describe the data, are summarized in Table 2-1. Table 2-1. Summary of the Format Descriptors Data Conversion Type Character Format Descriptor A R Logical L Real D E F G Integer I Monetary M Numeration N Octal O K @ Hexadecimal Z Note 2-10 Formatted Input/Output Forms A[w ] R[w ] L[w ] D[w.d ] E[w.d [Ee ]] F[w.d ] G[w.d [Ee ]] I[w [.m ]] M[w.d ] N[w.d ] O[w [.m ]] K[w [.m ]] @[w [.m ]] Z[w [.
The edit descriptors control the positioning and formatting of numeric, Hollerith, and logical elds on input and output lines. The edit descriptors do not cause data conversions and, with the exception of the Q descriptor, are not associated with the variables on the READ, WRITE, or PRINT statements. The edit descriptors are summarized in Table 2-2, where n represents a positive, nonzero number. Table 2-2.
This section describes the format and edit descriptors in detail. Format Specifications In the examples for this chapter, 1 represents a blank space and t represents eight binary zeros. Note Integer Format Descriptors: I, O, K, @, Z 2-12 Formatted Input/Output The I, O, K, @, and Z format descriptors provide formatting for integer data types. The general speci cations are: I[w [.m ]] O[w [.m ]] K[w [.m ]] @[w [.m ]] Z[w [.
The Input Field The Iw format descriptor interprets the next w positions of the input record. You can omit the plus sign for positive integers; you must not have a decimal point in the input record.
The Z input eld contains these hexadecimal digits: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A or a, B or b, C or c, D or d, E or e, and F or f. If the number of digits is too long for the integer variable, unde ned results occur. If a nonhexadecimal digit is used, an error occurs; no leading plus or minus sign on input is allowed. The variable receiving the hexadecimal input must be an INTEGER*2 or INTEGER*4 data type.
The Output Field The I, O, K, @, and Z descriptors each produce a distinctive output format. The I and Z Output Format The I and Z format descriptors handle the output eld in the same way. The I descriptor writes numbers in an integer format; the Z descriptor writes hexadecimal data. For the I or Z descriptor, if the eld width w is smaller than the number of digits needed to represent the value, the eld is lled with asterisks.
The following program compares the output generated by the I, O, and Z formats. PROGRAM int_outputs INTEGER*4 int int = 12 WRITE(6, '(11X, "I9", 15X, "O11", 15X, "Z9")') DO i = 1, 9 WRITE(6,100) int, int, int IF (i .NE.
Real Format Descriptors: F, D, E, G The F, D, E, and G format descriptors provide formatting for REAL*4, REAL*8, REAL*16, COMPLEX*8 and COMPLEX*16 data types. Complex values are treated as pairs of real values. The general speci cations are: F[w.d ] E[w.d [Ee ]] D[w.d ] G[w.d [Ee ]] where w is the total eld width, d is the number of digits after the decimal point, and e is the number of digits for the exponent. The Input Field The F, D, E, and G format descriptors handle the input eld in the same way.
The input statement READ(5, '(F6.2)') a can read any of the following input values: Input Field 1123 123456 12345678 +12345678 12.345 -123.45 1234E3* 123E3 123E-3 12.E-3 1234D3 123.D3 blanks " Equivalent Assignment = 1.23 a = 1234.56 a = 1234.56 a = 123.45 a = 12.345 a = -123.4 a = 12340.0 a = 1230.0 a = 0.00123 a = 0.120 a = 0.1234D+05 a = 0.123D+06 a = 0.0 a First column of input eld 1234E3|> 1234000|> 12340.00 If Ee falls within w eld (Fw.
The Output Field The F, E, D, and G descriptors each produce a distinctive output format. The F Output Format The F format descriptor writes numbers in a xed-point format. That is, the decimal point can be xed d places from the right of the number. The eld width w should always be at least two greater than the total number of digits you want printed; this leaves room for a sign and a decimal point. The E Output Format The E format descriptor writes any oating-point type numbers in exponential format.
PROGRAM real_formats * * This program shows a comparison of the F, E, and G format descriptors: REAL*4 realvalue realvalue = 0.1234567E-3 WRITE(6, '(12X, "F13.7", 16X, "E13.7", 16X, "G13.7")') DO i = 1, 14 WRITE(6,100) realvalue, realvalue, realvalue realvalue = realvalue * 10.0 100 END DO FORMAT (6X,"{",F13.7,"}",6X,"{",E13.7,"}",6X,"{",G13.7,"}") END The output of the above program follows: F13.7 { .0001234} { .0012345} { .0123456} { .1234567} { 1.2345669} { 12.3456688} { 123.4566956} { 1234.
Numbers are always right-justi ed into the output eld, with the exception of non-exponential data formatted by the G descriptor, as shown above. Note that in the list printed by the F descriptor, only the leftmost seven digits of the number are signi cant. Also, positive numbers over 99999.99 cannot be printed in F13.7 format because eight places are taken up by the seven fractional digits and the decimal point, leaving only ve places for digits to the left of the decimal point.
descriptors because the substrings speci ed in the output variable list are 5 and 6 bytes in length, respectively.
The Rw format descriptor is an HP extension to the ANSI 77 Standard, which provides compatibility with other versions of FORTRAN. The di erence between Aw and Rw occurs only when the speci ed eld width w is less than the number of characters speci ed by the I/O variable. The di erences are as follows: Using the Aw format descriptor, input data is left-justi ed into the input variable. The remaining positions are blank- lled. On output, the leftmost characters of the output variable are written.
If the speci ed eld width w is greater than the number of characters speci ed by the I/O variable, the Aw and Rw format descriptors behave in the same way. Input data is taken from the rightmost characters of the input eld. Output data is right-justi ed into the output eld. This is shown in Figure 2-3. Figure 2-3.
The Input Field With the A descriptor, if the eld width w is less than the length of the character variable, the characters are stored left-justi ed in the variable with the remainder of the variable lled with blank characters. With the R descriptor, if the eld width w is less than the length of the character variable, the characters are stored right-justi ed in the variable, preceded by null characters.
With the A or R descriptor, if the eld width w is larger than the length of the character variable, the rightmost characters are stored and the remaining characters are ignored. For example, the program below shows how character data is input.
For example, the program: PROGRAM widthsmaller_output CHARACTER char*10 ! Declare char to be 10 characters char = 'ABCDEFGHIJ' WRITE (6, '(1X, A3)') char WRITE (6, '(1X, R3)') char END ! Write only 3 characters ! Write only 3 characters produces the following output: ABC HIJ With the A or R descriptor, if the eld width w is greater than the length of the character variable, the characters are right-justi ed in the eld, with blanks on the left.
The program below also shows how the A and R format descriptors di er. The program uses the input value abcdef.
The A[w ] and R[w ] character format descriptors can be used with integer and real data types by specifying the NOSTANDARD compiler directive. The data is output in reverse order, starting at the right and progressing to the left. For example, the following program: c program demo Output numeric data with character format using an external write.
Logical Format Descriptor: L The L format descriptor de nes elds for logical data. The form of the descriptor is: L[w] where w is the width of the eld. The Input Field If the rst nonblank characters in the input eld are T or .T, the value .TRUE. is stored in the logical variable. If the rst nonblank characters in the input eld are F or .F, the value .FALSE. is stored in the logical variable. If the rst nonblank characters are not T, .T, F, or .F, an error occurs.
For example, the program: PROGRAM l_format_output LOGICAL logical1, logical2 logical1 = .FALSE. logical2 = .TRUE. WRITE (6, '(1X, L5)') logical1 WRITE (6, '(1X, L2)') logical2 END produces the following output: 1111F 1T Repeating Specifications The format descriptors can be repeated by pre xing the descriptor with a positive, unsigned integer specifying the number of repetitions. For example, the statement: 100 FORMAT (3F10.5, 2I5) 100 FORMAT (F10.5, F10.5, F10.5, I5, I5) 100 FORMAT (I5, 3(F10.
Correspondence Between the I/O List and Format Descriptors Usually there is a one-to-one correspondence between the items in the I/O list and the accompanying format descriptors. If, however, there are fewer items in the I/O list than corresponding format descriptors, the remaining format descriptors are ignored. For example, the statements: a = 5.0 b = 7.0 WRITE(6, '(1X, F6.1, F6.2, " id = ", I5, I2)') a, b do not use the I5 and the I2 descriptors.
The format statements above treat the rst three data items i, a, and j in each I/O list the same. However, the reused portion of the format speci cation is altered by nested format speci cations. The rst FORMAT statement shows that, in the absence of nested format descriptors, the entire list of format descriptors is reused. The second FORMAT statement shows how the reused portion of the FORMAT statement can contain additional nested speci cations.
Monetary Format Descriptor: M The Mw.d format descriptor de nes a eld for a real number without an exponent ( xed-point) written in monetary form. The general speci cation is: M[w.d ] where w is the width of the eld and d is the number of digits after the decimal point. The Input Field On input, the Mw.d format descriptor causes interpretation of the next w positions of the input record as a real number without an exponent.
The Output Field On output, the Mw.d format descriptor causes output of a numeric value in ASCII character xed-point form, right-justi ed with commas and a dollar sign. The least signi cant digit (position d ) is rounded. If needed, a leading minus sign is printed before the dollar sign. In addition to the number of numeric digits, the eld width w must allow for the number of commas expected plus four characters to hold the sign, the dollar sign, the decimal point, and a rollover digit (if necessary).
Numeration Format Descriptor: N The Nw.d eld descriptor de nes a eld for a real number without an exponent ( xed-point) written in numeration form (that is, with commas, which are then ignored, in the input eld). The general speci cation is: N[w.d ] where w is the width of the eld and d is the number of digits after the decimal point. The Input Field On input, the Nw.d eld descriptor causes interpretation of the next w positions of the input record as a real number without an exponent.
The Output Field On output, the Nw.d eld descriptor causes output of a numeric value in ASCII character xed-point form, right-justi ed with commas. The least signi cant digit is rounded. If needed, a leading minus sign is printed before the most signi cant digit. In addition to the number of numeric digits, the eld width w must allow for the number of commas expected, plus three characters to hold the sign, the decimal point, and a rollover digit (if necessary).
Processing New Lines The /, NN, NL, and $ descriptors handle the control of new lines. The / Descriptor The / edit descriptor terminates the current line and begins processing a new input or output line. On input, a slash indicates that data will come from the next line; on output, a slash indicates that data will be written to the next line. Commas separating edit descriptors and separating consecutive slashes are not needed.
Handling Character Positions The X, T, TL, and TR edit descriptors handle character position control. The X Descriptor The X edit descriptor skips character positions in an input or output line. The form of the descriptor is: nX where n is the number of positions to be skipped from the current position; n must be a positive nonzero integer. On input, the X edit descriptor causes the next n positions of the input line to be skipped.
The T Descriptor The T edit descriptor provides tab control. The form of the descriptor is: Tn where n is a positive, nonzero integer indicating number of columns. When the T edit descriptor is on a format line, input or output control skips right or left to the character position n ; the next descriptor is then processed. Be careful not to skip beyond the length of the record. For example, consider this program: PROGRAM t_edit READ (5, 100) a, b 100 FORMAT (T6, F4.1, TI5, F6.
The TL Descriptor The TL edit descriptor provides tab control. The form of the descriptor is: TLn where n is a positive, nonzero integer indicating number of columns. When the TL edit descriptor is on a format line, input or output control skips left n column positions from the current cursor position. If n is greater or equal to the current cursor position, the control goes to the rst column position.
The TR Descriptor The TR edit descriptor provides tab control. The form of the descriptor is: TRn where n is a positive, nonzero integer indicating number of columns. When the TR edit descriptor is on a format line, input or output control skips right n column positions from the current cursor position. Be careful not to skip beyond the length of the record. For example, the program: PROGRAM tr_edit a = 123.4 b = 1234.11 WRITE (6, 100) a, b 100 FORMAT (1X, F5.1, TR5, F7.
Handling Literal Data The ', ", and H edit descriptors handle literal data. The ' and " Descriptors Paired apostrophe (') and quotation mark (") edit descriptors write character strings; the paired symbols delimit a string of characters, which can include blanks. The ' and " descriptors are preferred over the H edit descriptor.
The H Descriptor The H (Hollerith) edit descriptor writes character strings. The H descriptor has the form: nHstring where n is the number of characters in the string and string is the string of characters. The string of characters is not delimited with quotation marks. For example, the program: 100 PROGRAM h_edit pi = 3.14159 WRITE (6, 100) pi FORMAT (1X, 21HThe value of "pi" is , F7.5) END produces the following output: The value of "pi" is 3.
END Formatted Input/Output 2-45
If the input to this program is: 123.4567 123.4567 123.4567 123.45E0 the values stored are as follows: value value value value 1 2 3 4 = = = = 123.4567 12345.67 1.234567 123.4500 On output, the scale factor a ects the D, E, and F format descriptors. The scale factor a ects the G format descriptor only if Gw.d is interpreted as Ew.d . When using the P edit descriptor with the D, E, or G format descriptor, the forms are as follows: nPD or nPDw.d nPE or nPEw.d or nPEw.dEe nPG or nPGw.d or nPGw.
For example, the program: PROGRAM p_edit_output pi = 3.14159 C Write without a scale factor WRITE (6, '(2X, "FORMAT", 10X, "VALUE"/)') WRITE (6, '(1X, " D10.4", 5X, D10.4/)') pi C Write with a WRITE (6, WRITE (6, WRITE (6, WRITE (6, WRITE (6, scale '(1X, '(1X, '(1X, '(1X, '(1X, factor on the D "-3PD10.4", 5X, "-1PE10.4", 5X, " 1PE10.4", 5X, " 3PD10.4", 5X, " 3PE10.4", 5X, and E format descriptors -3PD10.4)') pi -1PE10.4)') pi 1PE10.4)') pi 3PD10.4)') pi 3PE10.
If the P descriptor does not precede a D, E, F, or G descriptor, it should be separated from other descriptors by commas or slashes. For example, the statement: 100 FORMAT(1X, 2P, 3(I5, F7.2)) scales the F format descriptor value. If the P descriptor does precede a D, E, F, or G descriptor, the comma or slash is optional. For example, the program: PROGRAM p_edit_output_2 int = 5 real = 2.2 pi = 3.14159 * Output values without a scale factor: WRITE (6,50) int, real, pi 50 FORMAT (1X, I2, 3X, F14.
Printing Plus Signs: The S, SP, and SS Descriptors The S, SP and SS edit descriptors can be used with the D, E, F, G, and I format descriptors to control the printing of optional plus signs (+) in numeric output. A formatted output statement does not usually print the plus signs. However, if an SP edit descriptor is in a format speci cation, all succeeding positive numeric elds will have a plus sign. The eld width w must be large enough to contain the sign.
Terminating Format Control: The Colon Descriptor The colon (:) edit descriptor conditionally terminates format control, just as if the nal right parenthesis in the FORMAT statement has been reached. If there are more items in the I/O list, the colon edit descriptor has no e ect. For example, the program: PROGRAM colon_edit value1 = 12.12 value2 = 34.34 value3 = 56.56 WRITE(6,100) value1, value2, value3 100 FORMAT(1X, 'Values = ', 3(F5.2, :, ', ')) END produces the following output: Values = 12.12, 34.
However, the program: PROGRAM example2 10 OPEN(9, FILE='datafile') READ (9,10) i READ (9,10) j FORMAT (5(I2, :, /)) PRINT *, i PRINT *, j CLOSE(9) END produces this output: 12 24 In the rst example, the / descriptor causes the record containing the value 24 to be skipped. In the second example, the colon terminates format control before the / descriptor because no more list items remain in the I/O list.
Handling Blanks in the Input Field The BN and BZ edit descriptors are used to handle blanks in the input eld. The BN Descriptor The BN edit descriptor is used with the D, E, F, G, I, O, K, @, and Z format descriptors to interpret blanks in numeric input elds. If BN is speci ed, all embedded blanks are ignored, the input number is right-justi ed within the eld width, and, if needed, the eld is padded with leading blanks. An input eld of all blanks has a value of zero.
int2 = 2 int3 = 30000 Formatted Input/Output 2-53
The BZ Descriptor The BZ edit descriptor is used with the D, E, F, G, I, O, K, @, and Z format descriptors to interpret blanks in numeric input elds. If BZ is speci ed, trailing and embedded blanks are interpreted as zeros. An input eld of all blanks has a value of zero. For example, consider this program: PROGRAM bz_edit READ (5,100) int1, val1, int2 100 FORMAT (I3, BZ, F6.2, I3) END If the input to this program is: 111141.
Alternative Methods of Specifying Input/Output There are alternative methods of specifying an I/O statement.
Using the Implied DO Loop The implied DO loop is used with the READ, WRITE, and PRINT statements. An implied DO loop contains a list of data elements to be read or written, and a set of indexing parameters. Following is an implied DO loop: PRINT *, (apple, i = 1,3) where apple is the index parameter and i is the data element. The statement above prints the value of apple three times. If apple is initialized to 35.6, the output would look like this: 35.6 35.6 35.
Implied DO loops are useful for controlling the order in which arrays are output. You can output an array in column-major or row-major order.
The program produces this output: 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 Implied DO loops for input or output are not just used with arrays. The following program prints a table of degrees and the sine of each, in steps of 10 degrees. PROGRAM sine WRITE (6,100) (d, SIN(d*3.14159/180.), d=0,360,10) 100 FORMAT (1X, F4.0, F9.
The program produces the following output: 0. 10. 20. 30. 40. 50. 60. 70. 80. 90. 100. 110. 120. 130. 140. 150. 160. 170. 180. 190. 200. 210. 220. 230. 240. 250. 260. 270. 280. 290. 300. 310. 320. 330. 340. 350. 360. .00000 .17365 .34202 .50000 .64279 .76604 .86602 .93969 .98481 1.00000 .98481 .93969 .86603 .76605 .64279 .50000 .34202 .17365 .00000 -.17365 -.34202 -.50000 -.64279 -.76604 -.86602 -.93969 -.98481 -1.00000 -.98481 -.93969 -.86603 -.76605 -.64279 -.50000 -.34202 -.17365 -.
3 File Handling HP FORTRAN 77 performs input/output operations with a wide range of devices, including disk drives, terminals, and line printers, as well as the computer's own memory. Internal le I/O provides a way to perform data conversions with character data in computer memory. This chapter describes I/O operations with disk les and internal les. Disk Files The source or destination of an HP FORTRAN 77 I/O operation is speci ed by a unit number.
breaks the connection between unit 9 and the connected le. The CLOSE statement has the e ect of ushing bu ers used for le I/O and releasing the unit number for connection to another le if necessary. When a program terminates, an automatic CLOSE is performed on each connected unit in the program. However, it is good practice to include a CLOSE statement when le I/O is complete. Default File Properties The statements shown so far illustrate the simplest le handling commands possible.
The STATUS Specifier The STATUS speci er in the OPEN statement assigns a status to the le. The four types of status are described in Table 3-1. Table 3-1. Status Types Status Type 'NEW' 'OLD' 'UNKNOWN' 'SCRATCH' Description The le will be created by the OPEN statement. If the le exists, an error occurs. This status is useful to protect against writing over an existing le. The le is expected to already exist. If the le does not exist, an error occurs.
connects the logical unit 9 to the le datafile. If an error occurs in the opening of the le, control transfers to the statement labeled 180.
The IOSTAT Specifier The IOSTAT speci er in the OPEN statement names the integer variable where the system returns the error message number. The values returned in this integer variable are summarized in Table 3-3. Table 3-3. The IOSTAT Specifier Value of IOSTAT Integer Variable Meaning Zero No error occurred. Greater than zero An error occurred; an error message number is returned. The error message number refers to runtime errors. Refer to the HP for a description of the error message.
Creating a New File Using STATUS='NEW' The OPEN statement with STATUS='NEW' creates a new le. A le can be created by one program and used by another. The program below creates a le and uses the OPEN statement speci ers STATUS, ERR, and IOSTAT to leave the existing le unchanged with repeated runs of the program. PROGRAM open_specifiers1 INTEGER*4 account_num, number, quantity REAL*4 price C C C C Create file "pfile". If an error occurs, ios will contain the runtime error number.
* WRITE(6,*) stmt_name, ' error: the file ', file_name, ' was not found.' ELSE IF (ios .LE. eof) THEN WRITE(6,*) stmt_name, ' End of file ', file_name ELSE WRITE(6,*) stmt_name, ' error', ios, ' on file ', file_name END IF END In this program, unit 9 is connected to the le pfile. You are prompted to enter data for the variables number, quantity, and price. The variable number represents the number of transactions in the pfile and controls the number of iterations through the DO loop.
The error subroutine in this program includes checks for some speci c errors. The error \File not found" (reported for STATUS='OLD' les) and \File already exists" (reported for STATUS='NEW' les) generate positive return values for ios. After the error routine, the STOP statement halts the program and prints the message \Error termination".
To read data from an existing le, you must rst open the le with the OPEN statement. For example, the following program opens and reads the existing le pfile that was created in the previous example. By specifying STATUS='OLD', the le pfile must exist or else the program will terminate.
SUBROUTINE report_error(ios, stmt_name, file_name) INTEGER*4 CHARACTER PARAMETER ios, eof, found, not_found stmt_name*(*), file_name*(*) (eof = -1, found = 918, not_found = 908) IF (ios .EQ. found) THEN WRITE(6,*) stmt_name, ' error: the file ', * file_name, ' already exists.' ELSE IF (ios .EQ. not_found) THEN WRITE(6,*) stmt_name, ' error: the file ', * file_name, ' was not found.' ELSE IF (ios .LE.
Appending to a File To write data to an existing le, you must rst open the le with the OPEN statement. For example, the following program opens and writes to the existing le prices, whose contents are as follows: 3 2 6 1 14 5.16 9.25 1.72 15.91 2.75 The program rst nds the end of the le, and then accepts the new data. PROGRAM write_exist LOGICAL PARAMETER INTEGER*4 REAL*4 forever (forever = .TRUE.
After the program executes, the contents of prices look like this: 3 2 6 1 14 1 5 5.16 9.25 1.72 15.91 2.75 1.50 2.25 The new data is appended to the end of the existing le. File Access The examples so far have been sequential access les; unless otherwise speci ed in the OPEN statement, les are opened for sequential access. But, FORTRAN les can be accessed (read or written) in three ways: sequential, direct, or indexed sequential.
Figure 3-1. Sequential Access Files Note that each record in a sequential access le can be a di erent size. The default speci ers in the OPEN statement for sequential access les are summarized below: Speci er STATUS ACCESS FORM BLANK Default 'UNKNOWN' 'SEQUENTIAL' 'FORMATTED' 'NULL' The BLANK speci er describes how blanks within numbers are treated on input from formatted les. If BLANK='NULL', blanks are ignored; if BLANK='ZERO', blanks are treated as zeros.
Direct Access Files Direct access les are read and written according to the record number; the record number can then be used in random order. Each record in the le has a record number that is speci ed by the REC speci er on a READ or WRITE statement. Each record in a direct le must be the same size, as speci ed in the OPEN statement. A diagram of how a direct access le is structured is shown in Figure 3-2. Figure 3-2.
Once established, the record number of a speci c record cannot be changed or deleted, although the record can be rewritten. The records can be read or written in any order. For example, record number 3 can be written before writing record number 1. The records of a direct access le cannot be read or written using list-directed formatting. Because a direct access le does not have an end-of- le record, the END speci er in the direct access READ or WRITE statement is not allowed.
The program below shows how to create and write data to a direct access le.
The program below reads and prints the contents of the rst ve records in reverse order from the le dfile. PROGRAM direct_read INTEGER quantity C Open the file "dfile" OPEN(2, FILE='dfile', ACCESS='DIRECT', RECL=120) C Read and print the first five records: DO i = 5, 1, -1 READ(2, REC=i) quantity, price WRITE(6, '(1X, I5, I5, F9.2)') i, quantity, price END DO END The program produces the following output: 5 4 3 2 1 3 14 0 60 9 74.70 16.00 0.00 1.50 9.
Indexed Sequential Access Files Indexed sequential les (ISAM) are read and written randomly by a key or sequentially without a key. The key is part of the record. Files are of xed length. Each record in the le has a primary key and one or more secondary or optional keys. These keys are part of the record that is being written into the le. Each record in an ISAM le must be the same size as speci ed in the OPEN statement by RECL.
The following table shows how a le is speci ed variable or xed length in an OPEN statement. ACCESS RECL RECORDTYPE SEQUENTIALAbsent SEQUENTIALPresent DIRECT DIRECT KEYED KEYED KEYED Absent Present Present Present Absent Variable Fixed Fixed File Type. Variable le. Variable le (RECL= maximum record length) Error. Fixed record length le. Error. Fixed record length ISAM le. Error.
For example, the statement: OPEN (10,FILE='file1',KEY=(1:4:integer,10:15:character),ACCESS='keyed') connects a le named file1 to logical unit 10. The program below shows how to create and write data to an indexed sequential le.
READ (5,10) customer_rec.city WRITE (6,'(A,NN)') "state: " READ (5,13) customer_rec.state WRITE (6,'(A,NN)') "zip: " READ (5,*) customer_rec.zip WRITE (10,err=200) customer_rec GOTO 8 10 11 12 13 FORMAT(A15) FORMAT(A1) FORMAT(A20) FORMAT(A2) 100 STOP 200 PRINT *,' error in writing' END The program below shows how to read an ISAM le with an alternate key and to read it sequentially.
C C Read a record with an alternate key( last name ) and list all the names with that name as the last name WRITE(6,'(A,NN)') " enter the last name: " READ (5,10) temp_name 10 FORMAT (A15) READ (10,KEYEQ=temp_name,KEYID=1,ERR=101) customer_rec WRITE (6,11) customer_rec.phone_num, customer_rec.last_name, customer_rec.first_name 11 FORMAT (I7,X4,A,X2,A) 1 C C Read sequentially and list phone number and the name until last name changes. done = .false.
Unformatted I/O Unformatted I/O statements do not use format descriptors and do not convert the data on input or output. The data is transferred in internal (binary) representation to the external device. Unformatted I/O cannot be used for internal or formatted les. Note that terminals are opened as formatted les. Unformatted Input The unformatted READ statement transfers one line from the speci ed unit to the storage locations of the variables listed in the READ statement list.
Using Formatted and Unformatted Files FORTRAN les can be either formatted or unformatted. If not speci ed in the OPEN statement, sequential les are defaulted to be formatted and direct access les are defaulted to be unformatted. A formatted le is read and written with formatted I/O statements. That is, the READ or WRITE statements contain a format or list-directed speci cation. An unformatted le is read and written with unformatted I/O statements.
The unformatted WRITE statement writes the data to the le without conversion. The number of bytes written to the disk correspond to the number of bytes allocated to the variables in the declaration statement. In this example, there is a 4-byte real, a 4-byte integer, and a 16-byte character variable, for a total of 24 bytes. The advantage of the unformatted WRITE statement is that the numeric data takes up less room on the disk and that the slow conversion from binary to character format is not done.
Using the INQUIRE Statement The INQUIRE statement returns information about a le or unit. The information returned can be about one of the following: A le that is not connected to a unit A le that is connected to a unit A FORTRAN I/O unit For example, the statement: INQUIRE(FILE='abcfile', ERR=999, EXIST=ex, ACCESS=ac) returns information about the le abcfile to the variables ex and ac. If an error occurs during the INQUIRE, control transfers to the statement labeled 999.
The program below opens the le pfile and uses the INQUIRE statement to return information about the le to the variables ios, iop, ex, and ac. PROGRAM inquire_info LOGICAL ex, iop CHARACTER*10 ac OPEN(8, FILE='pfile') * INQUIRE(FILE='pfile', IOSTAT=ios, OPENED=iop, EXIST=ex, ACCESS=ac, ERR=100) PRINT *, "iop = ", iop PRINT *, "ex = ", ex PRINT *, "ac = ", ac ! iop returns T if the file is opened ! ex returns T if the file exists ! ac returns the type of file access IF (ios .NE.
Similarly, the program below uses the INQUIRE statement to return information about unit 8. Note that this INQUIRE statement refers to the connection to I/O unit 8, not to the le pfile.
Positioning the File Pointer The BACKSPACE, REWIND, and ENDFILE statements control the position of the le pointer within a sequential access le. The unit speci ers UNIT, IOSTAT, and ERR can be used on the le positioning statements. The BACKSPACE Statement The BACKSPACE statement positions the le pointer back one record. For example, the statement: BACKSPACE 10 moves the le pointer for unit 10 back one record. The REWIND Statement The REWIND statement positions the le pointer at the beginning of the le.
Example of Using the File Positioning Statements The le positioning statements are used in the following program: PROGRAM positioning INTEGER*4 quantity REAL*4 price C Open the file connected to unit 10: OPEN(10, FILE = 'pfile') C Read some records: DO i = 1, 5 READ(10,'(I10, F9.2)') quantity, price END DO C Move the file pointer from unit 10 to the previous record: BACKSPACE 10 C C C C Move the file pointer to the initial point in the file connected to logical unit 10.
File Handling Examples This section demonstrates the use of several options of the le handling statements. Computing the Mean of Data in a Sequential File The following program computes the mean of all the data items in the disk le data. The le contains an unknown number of records, with each record containing one real number. PROGRAM compute_mean sum = 0.
Inserting Data Into a Sorted Sequential File This program inserts a single number in the proper position in a sorted sequential le.
4.0 5.0 and you run the program to insert the number 3.5, the le newfile looks like this after execution: 1.0 2.0 3.0 3.5 4.0 5.
Internal les provide a way of reformatting, converting, and transferring data from one area of memory to another; no input or output devices are used. If you use internal les to reformat data, you do not have to write data to a le and reread the le with a di erent format. Instead, internal les allow conversion between numeric and character data types. An internal le is an area of storage internal to the program.
You can use the READ statement to convert data.
Writing to an Internal File Data is written to internal les with a formatted WRITE statement. The name of the internal le is speci ed in the WRITE statement. For example, the statement: or: WRITE(UNIT=address_var, FMT='(I10)') street_address WRITE(address_var, '(I10)') street_address writes the value of street_address into the rst ten positions of the internal le address_var. The variable address_var must be a variable or array of type CHARACTER.
Another example of writing to a character variable in an internal le is shown below, where a format speci cation is built at execution time. This program only shows how internal les work, not necessarily e cient programming practices.
4 HP FORTRAN 77/iX File Operations This chapter describes the following: Characteristics requested by the OPEN statement processor Prede ned units and les Creating and closing les Carriage control les Magnetic tapes Procedures for le handling The OPEN Statement Processor The FORTRAN 77 OPEN statement gives you more control over le connection and le characteristics than older versions of FORTRAN. The run-time library translates the OPEN statement to call the MPE/iX FOPEN system intrinsic.
Predefined Units and Files Units ve and six are the prede ned I/O units for FORTRAN 77. These units are opened by the I/O library before the rst I/O statement is executed. Unit ve is opened as formal le designator FTN05, which defaults to $STDINX. ($STDIN is not the default; this prevents logging o if an input line of :EOF is entered and allows input of lines containing a colon in the rst position.) The formal designator for unit 6 is FTN06, which defaults to $STDLIST.
FTN01 Through FTN99 (Excluding FTN05 and FTN06) For compatibility with FORTRAN 66/V, the FORTRAN 77 I/O library automatically opens units 1 through 99 (excluding 5 and 6) to the formal le desginators FTN01 through FTN99, respectively. OPEN statements are not required for these les, though a :FILE equation is usually required (as it is in FORTRAN 66/V). Units 0 and those greater than 99 must be opened with an OPEN statement before being used.
Creating Files with the OPEN Statement STATUS='NEW' STATUS='OLD' STATUS='SCRATCH' STATUS='UNKNOWN' 4-4 Existing les (OLD or TEMP) connected with the OPEN statement already have de ned characteristics; therefore, the arguments to the FOPEN intrinsic are ignored. Similarly, FILE equations referenced in the OPEN statement are overridden by the characteristics of the corresponding device or le.
FORM='UNFORMATTED' and FORM='FORMATTED' ACCESS='SEQUENTIAL' The FORM option speci es the type of transfers that can be performed on the le. FORM='UNFORMATTED' implies that only unformatted (binary) transfers are performed, so an MPE/iX BINARY le is requested in the corresponding FOPEN intrinsic. When the OPEN statement speci es FORM='UNFORMATTED', bit 13 is cleared to zero in the FOPTIONS parameter. The default FORM='FORMATTED' implies that only formatted and/or list-directed transfers can be performed.
ACCESS='DIRECT' 4-6 OPEN statements that specify ACCESS='DIRECT' must include the maximum length of the records to be read or written. This allows xed record length les of the appropriate length to be requested in the FOPEN. Accordingly, bits eight and nine of the FOPTIONS are set to zero for the FOPEN call. The required RECL speci er sets the record length of the le created.
Closing Files Executing the CLOSE Statement Note Once opened by prede nition or with the OPEN statement, les are closed either by executing a CLOSE statement or by terminating the program. The CLOSE statement explicitly causes the corresponding unit to be closed. The disposition of the le is controlled by the STATUS speci er in the CLOSE statement, with the exception of STATUS='SCRATCH' les.
The preconnected unit six (FTN06) is opened with carriage control (CCTL). When initially opening empty les (EOF points to zero), the CCTL bit and the device type are checked. The appropriate FWRITE is then performed to set the le for prespacing. Prespacing mode is when the carriage control character is in column one of the formatted output.
Using Magnetic Tapes Magnetic tapes can be directly read or written from FORTRAN 77 programs by a FILE equation. As a MIL-SPEC 1753 extension to the ANSI standard, such tapes can be read or written in multiple logical les on the same tape. The most portable format is a xed record length ASCII le with a speci ed blocking factor of one. However, the blocking factor of one wastes tape because the interrecord gaps are longer on the tape than on a single formatted record of normal length.
Using the File Handling Procedures FSET Procedure This section describes the FSET, FNUM, and UNITCONTROL procedures. Refer to the HP FORTRAN 77/iX Reference Manual for more details on these procedures. The FSET procedure changes the MPE/iX operating system le number assigned to a given FORTRAN logical unit number in the le table.
The following program shows how to use the FSET procedure to assign a FORTRAN logical unit number.
This is the output of the program: Old file number = 11 FOPEN number = 10 SMILEY FACE MICKEY MOUSE SLIM JIM CHARITY BELL DONALD DUCK JOE SMOE CLAIRE PLIMSOL INDIANA JONES JAKE FAKE File closed successfully FNUM Procedure The FNUM procedure returns the MPE/iX system le number assigned to a given FORTRAN 77 logical unit number. This procedure returns an INTEGER*2 or INTEGER*4 value.
UNITCONTROL Procedure The UNITCONTROL procedure allows an HP FORTRAN 77/iX program to request several actions (see below) for any FORTRAN 77 logical unit. The UNITCONTROL procedure is called as follows: CALL UNITCONTROL(unit,opt) Item Description/Default Restrictions Must be nonnegative. Positive integer (INTEGER*2 or INTEGER*4) that speci es the unit number of the le to be used. Integer (INTEGER*2 or INTEGER*4) that None. speci es the option (see Table 4-1).
The program below shows how to use the FNUM and UNITCONTROL procedures. The SHORT compiler directive forces the integer and logical default size to two bytes.
C Establish MPE/iX filenumbers for output file (MAIL3) by C referencing the FNUM procedure outputfile(1) = FNUM(22) outputfile(2) = 0 C Merge the files > CALL HPMERGEINIT(status,infiles,,outputfile,, keysonly,numkeys,keys,,,,,error) IF (error .NE.
This is the output of the program: PLAINS LOIS KING ALI BLACK JOHN KNEE SWASH ANIMAL MULE WHITETAIL JAMES JANE PRAIRIE JOHN MALLARD JENNA KARISSA SNOWSHOE MOUNTAIN SPACE SWAMP NASTY BIGHORN GREY 4-16 HP FORTRAN 77/iX File Operations ANTELOPE ANYONE ARTHUR BABA BEAR BIGTOWN BUCKLER BUCKLER CRACKERS DEER DEER DOE DOE DOG DOUGHE DUCK GRANDTR GRANDTR HARE LION MANN RABBIT RATTLER SHEEP SQUIRREL 201 OPENSPACE AVE 6190 COURT ST 329 EXCALIBUR ST 40 THIEVES WAY 47 ALLOVER DR 965 APPIAN WAY 974 FISTICUFF DR 497
5 Subprograms A subprogram is an independent section of code called by a main program or by another subprogram. Subprograms make programs more readable and easier to maintain, write, and debug. Subprograms can be grouped into these three categories: Subroutines Functions Function subprograms Statement functions Intrinsic functions Block Data Subprograms A program unit, such as a main program or a subprogram, is a sequence of FORTRAN statements. Table 5-1 summarizes the components of program units.
Subroutines Structure of a Subroutine Subroutines are user-written procedures that perform a computational process or a subtask for another program unit. Subroutines usually perform part of an overall task, such as solving a mathematical problem, performing a sort, or printing in a special format. Values are passed to the subroutine and returned to the calling program unit by using arguments or common blocks. The rst statement of a subroutine must be a SUBROUTINE statement.
The program produces the following output: num = num = num = num = num = final 1 2 3 4 5 count = 5 A program that indirectly calls itself is similar in principle to a subroutine that calls a procedure that in turn calls the original subroutine. The END statement in a subroutine causes control to be passed back to the calling program. The RETURN statement also transfers control back to the calling program.
Invoking Subroutines A subroutine is executed when a CALL statement is speci ed in a program unit. Here are some examples of CALL statements: CALL next(x, y) CALL last(a, *10, *20, b, i, k, *30) CALL noarg When the subroutine is executed, the actual arguments x, y, a, b, i, and k in the CALL statement are associated with their equivalent dummy arguments in this way: PROGRAM main . . .
Alternate Returns From Subroutines Normally control from a subroutine returns to the calling program unit at the statement following the CALL statement. However, you can specify an alternate return that allows control to return to the calling program unit at any labeled executable statement. An alternate return is speci ed in the called subroutine by the RETURN statement with an integer expression or constant that identi es the number of a statement label in the CALL statement.
statement. If an expression in a RETURN statement has a value that is either less than one or greater than the number of alternate return labels in the CALL statement, control is returned to the statement following the CALL statement.
An example of a program that uses alternate returns follows. The subroutine searches a le named parts to validate a part number. Each record in parts is an integer array of two elements; the rst is the part number and the second is a code. A negative code indicates an obsolete part number. All existing part numbers are in the le parts. The records in the le are ordered by increasing part number and, for simplicity, the search for a part number is sequential.
C Search for part number and set flags accordingly OPEN(111, FILE='parts', STATUS='OLD') DO WHILE (parts_file_record(1) .LT. part_number) READ(111,*) parts_file_record IF (parts_file_record(1) .EQ. part_number) THEN part_found_flag = .TRUE. IF (parts_file_record(2) .LT. 0) obsolete_flag = .TRUE. ENDIF END DO CLOSE(111) C Return to calling program depending on flags IF (obsolete_flag) RETURN 1 IF (.NOT.
FORTRAN functions can be grouped into categories, as summarized in Table 5-2. Functions Table 5-2. Categories of FORTRAN Functions Type of Function Function Subprogram Statement Function Intrinsic Function Description A user-de ned function A user-de ned single statement function A FORTRAN built-in function A function name in an expression causes the function to be evaluated; the function then assigns a value to the function name.
An example of a user-de ned function is shown below: PROGRAM main READ (5,'(2F10.0)') a, b x = bigger(a, b) 100 WRITE (6,100) a, b, x FORMAT (1X, 2F10.2, /, 1X, 'The largest value is', F10.2) END FUNCTION bigger(a, b) IF (a .LT.
Some examples demonstrating how to associate a value to the function name are shown below. Consider this function: INTEGER FUNCTION factorial(n) INTEGER fact, n fact = 1 10 DO 10 i = 2,n fact = fact * I CONTINUE factorial = fact END In the function factorial above, the value fact is assigned to the function name factorial. Note that the DO loop will not be executed if n equals zero or one. Here is another function: FUNCTION tot(num,sum) REAL num, sum IF (num .GE. 0.
Because a value is assigned to the function subprogram name, the value's data type must be de ned. The data type associated with the function name is determined in one of these ways: If the data type is included with the FUNCTION statement, the name is assigned that type. For example, a FUNCTION statement explicitly speci ed as an integer looks like this: INTEGER FUNCTION funcname() A function name cannot have the data type speci ed more than once in a program.
When you reference a character function, the length of the function must be the same as that declared in the function. There is always agreement of length if a length of asterisk (*) is speci ed in the function. For example, a character function and a program that calls the function are shown below. The function returns the character string with all preceding and trailing blanks removed. PROGRAM test CHARACTER*20 input_string, result, stringtrim DO WHILE (input_string(1:1) .NE.
A sample run, where 1 represents a blank, looks like this: Enter a string: :string: Enter a string: :four: Enter a string: :three: Enter a string: :blanks: Enter a string: : : Enter a string: :0: string 1111four three111 111blanks111 1 1111111 0 The value returned by the function is the value last assigned to the function name at the time a RETURN statement is executed in the function. Consider this example of a calling program unit and a function subprogram.
Two runs might look like this: Enter m and n: 7, 4 7 things taken Statement Functions 4 at a time = 35 Enter m and n: 10, 2 10 things taken 2 at a time = 45 A statement function is a user-de ned single-statement computation that can only be called in the program unit that de nes it. The form of a statement function is similar to an arithmetic, logical, or character assignment statement. Only one value is returned from a statement function.
A statement function can call another statement function. For example, the program below de nes a statement function that calls another statement function. PROGRAM functionex2 add(a, b, c) = a + b + c add25(d, e, f) = add(d, e, f) + 25.0 DATA value1, value2, value3 /5.0, 10.0, 15.0/ result = add25(value1, value2, value3) PRINT *, result END All statement function de nitions must precede the rst executable statement in the program unit and must follow any speci cation statements in a program unit.
functions, such as nding sines, cosines, and square roots of numbers. The HP FORTRAN 77/iX Reference Manual describes each intrinsic function in detail and discusses the data types of arguments allowed and the argument and function type.
Communication between the calling program and the referenced subprogam is accomplished by passing values through an argument list. An argument list consists of one or more items separated by commas and enclosed in parentheses. In addition, values can be passed through common blocks to and from subprograms. The calling program unit passes actual arguments to a subprogram. Dummy arguments \refer" to the same locations as actual arguments; therefore, arguments are passed by reference.
The arguments correspond to each other as follows: q is an array name, so the dummy parameter arry must be dimensioned in the subprogram. x is a real variable; the dummy parameter (z) in the second position of the subroutine argument list must also be a real variable. i corresponds to in1. r(1) is an element of array r and can correspond to a single variable name (tmp) (not dimensioned) or an array (dimensioned) in the dummy argument list.
DIMENSION j(10) de nes these arguments: z is a REAL variable; i is a REAL*8 variable; j is a 10-element INTEGER array.
The subroutine description: SUBROUTINE add(q, f, get) q = get(f) de nes these arguments: q and f are real variables and get is a function name. In the context in which get is used, get could either be an array or a function. But, because get was not declared as an array, get is a function name. All variable names are local to the program unit that de nes them. In a statement function, all actual variable names are local to that statement.
Passing Expressions You can use expressions as actual arguments; an actual argument can be any legal expression whose result is a value of the same data type as the dummy arguments. For example, consider these statements: CALL baseball(team + 5.0, player1, player2, * SQRT(3.
You can pass character expressions and character expressions involving concatentation of operands whose lengths are (*), indicating unde ned length.
When an actual argument is an expression, the dummy argument in the subprogram unit that corresponds to the actual expression should not be reassigned in the subprogram.
Passing Character Data When character data is passed to a subprogram, both the dummy and actual arguments must be a character data type. The length of the dummy argument must be less than or equal to that of the actual argument. If the length of the dummy argument is less than the length of the corresponding actual argument, only the leftmost characters of the actual argument, up to the length of the dummy argument, are associated with the dummy argument.
The dummy argument array must not extend beyond the end of the associated actual argument array. For example, the program: PROGRAM main CHARACTER a(10)*10 ! 10 elements of length 10 declared CALL sub(a) . . . END SUBROUTINE sub(b) CHARACTER b(20)*20 . . . END ! 20 elements of length 20 declared could have unexpected results. If an actual argument is a character substring, the length of the actual argument is the length of the substring.
Passing Arrays Functions and subroutines can process entire arrays. Association between an actual array argument and the corresponding dummy array argument follows the same rules described for single-valued arguments. The array name in a dummy argument list is de ned as an array in a type or DIMENSION statement within the subprogram, and a similar declaration appears in the invoking program for the actual array name. You should make sure that the declared array type is the same for both array names.
Adjustable Dimensions Normally, array bounds are speci ed by integer constants and are xed by the values of these constants. However, you can use adjustable arrays in subprograms. Adjustable dimensions allow you to create a subprogram that can accept varying sizes of actual array arguments. For adjustable declarations, one or more of the array bounds is speci ed by an expression involving integer variables or expressions, rather than by integer constants.
RETURN END Subprograms 5-29
The following output is produced by the program: 1 2 3 4 5 6 7 8 9 10 2 4 6 8 10 12 14 16 18 20 3 6 9 12 15 18 21 24 27 30 4 8 12 16 20 24 28 32 36 40 5 10 15 20 25 30 35 40 45 50 6 12 18 24 30 36 42 48 54 60 7 14 21 28 35 42 49 56 63 70 8 16 24 32 40 48 56 64 72 80 Assumed-Size Arrays 9 10 18 20 27 30 36 40 45 50 54 60 63 70 72 80 81 90 90100 The assumed-size array is another form of adjustable dimensions in subprograms.
A variable that dimensions a dummy argument in a bounds expression within a type or DIMENSION statement in a subprogram can appear either in a common block or as a dummy argument, but not both. Adjustable and assumed-sized array declarations cannot be used in COMMON statements, in main programs, or in BLOCK DATA subprograms. You can pass the names of functions and subroutines as arguments to other subprograms.
Multiple Entries into Subprograms A subroutine call or function reference usually invokes the subprogram at the entry point de ned by the SUBROUTINE or FUNCTION statement. The rst statement executed is the rst executable statement in the subprogram. However, you can use the ENTRY statement to de ne other entry points within the function or subroutine. The entry point can be anywhere within a function or subroutine after the FUNCTION or SUBROUTINE statement, but not within an IF block or DO loop.
A subroutine with entry points search and punctuation is shown below: SUBROUTINE linka(d, n, f) INTEGER d, n, f, table, document C C In subroutine linka, via primary entry point DO 10 i = 1, f, n . . . 10 CONTINUE RETURN ENTRY search(table, f) In subroutine linka, via entry point search DO 20 i = 1, f . . . 20 CONTINUE RETURN ENTRY punctuation(document) C In subroutine linka, via entry point punctuation DO 30 i = 1, 5 . . .
The order, type, and names of the dummy arguments in an ENTRY statement can di er from the dummy arguments in the FUNCTION, SUBROUTINE, and other ENTRY statements in the same subprogram. However, each reference to a function or subroutine must use an actual argument list that agrees in order, number, and type with the dummy argument list in the corresponding FUNCTION, SUBROUTINE, or ENTRY statement.
FUNCTION, SUBROUTINE, or ENTRY statement. An entry name cannot appear in an EXTERNAL statement.
Common Blocks Blank Common Blocks In addition to passing values through arguments, common blocks can provide communication between program units and subprograms. Before a FORTRAN program is executed, computer storage is allocated for each program and subprogram. In addition, a common block of storage is reserved for use by all program units. Program units de ne the data to be reserved in common blocks with the COMMON statement. There are two kinds of common blocks: blank common and labeled common.
REAL array1(2), array2(3) INTEGER i, j COMMON i, array1, j, array2 Subprograms 5-37
The common block would be accessed as follows: Word Item Name From Program Unit C Item Name From Program Unit A 1 i car(1,1) 2 array1(1) car(2,1) 3 array1(2) car(1,2) 4 j car(2,2) 5 array2(1) car(1,3) 6 array2(2) car(2,3) 7 array2(3) count As you can see, inconsistent COMMON statements make a program hard to follow. To avoid errors, modules containing a COMMON statement should specify the same organization of the common area.
Labeled Common Blocks In some programs, you might want to subdivide the common area into smaller blocks with each block having a unique name. To do this, the labeled form of the COMMON statement is used as follows: COMMON /name/list, ..., /name/list where name is the common block name and list is the list of variable names, arrays, and array declarators. Before a program is executed, one block of storage is allocated for each unique named common area that was speci ed from the program units.
To see how labeled common blocks work, consider this partial program: PROGRAM main COMMON var1, var2, var3 COMMON /block1/ var4, var5, var6 . . . END SUBROUTINE sub(x) COMMON /block1/ a, b, c . . . END FUNCTION func(y) COMMON f1, f2, f3 . . . END The items var4, var5, and var6 in the main program are in the common block named block1. The same storage words are referred to by the names a, b, and c in subroutine sub. The items var1, var2 and var3 in the main program are in blank common.
Block Data Subprograms Block data subprograms de ne the size and reserve storage space for common blocks. Block data subprograms can also initialize the variables and arrays declared in the common block. A block data subprogram begins with a BLOCK DATA statement and ends with an END statement. For example, consider this block data subprogram: BLOCK DATA datablock1 INTEGER i, n, t REAL x, y, z COMMON /block1/ n, t COMMON /block2/ i, x(10) DATA n, t /5, 25/ DATA x /10*1.
The name null is the optional name of a BLOCK DATA subprogram used to reserve storage locations for the named common blocks xxx and set1. Arrays iy and b are initialized in the DATA statements. The remaining elements in the common block can optionally be initialized or typed in the block data subprogram.
Using the SAVE Statement The SAVE statement retains the value of local variables after the execution of a RETURN or END statement in a function or subroutine. The SAVE statement allows data to be shared among subprograms because the values of entities are saved beyond the scope of the program units in which they are declared. However, an item in a common block can become unde ned or rede ned in another unit.
RETURN END The output of this program looks like this: 1 2 3 4 The variable count is incremented each time sub1 is called. The SAVE statement in the subroutine saves the value of count until the next call to sub1.
6 Writing Efficient Programs Note Ideally, a program should compile quickly, run quickly, and use a minimal amount of memory for code and data. You can take steps to minimize both time and space used by a program; however, you might have to trade one type of e ciency to achieve another. For example, on a machine with 32-bit words, your program might run faster if 32-bit integers (INTEGER*4) are used, but will use twice as much data space as using 16-bit integers.
Compile-Time Efficiency 6-2 Writing Efficient Programs To avoid ine cient compiler options, do not use compiler options that generate symbol table information, code o sets, and code listings. These options cause the compiler to generate additional information and should be used only when the information generated is needed for debugging.
Run-Time Efficiency Declare Integer and Logical Variables Efficiently Avoid Using Arrays Use Efficient Data Types The suggestions below help to decrease the time needed to run your program. Declare integer and logical sizes equal to 32 bits (4 bytes) which is the HP 3000 Series 900 word size. That is, use the defaults of INTEGER*4 and LOGICAL*4.
Eliminate Slow Arithmetic Operators When possible, replace slower arithmetic operations with faster operations. The arithmetic operations are listed below from fastest to slowest: Addition and subtraction Multiplication Division Exponentiation +0 * / ** (Fastest) (Slowest) In some cases, multiplication operations can replace exponentiation, addition operations can replace multiplication, and multiplication operations can replace division. For example, i = j**2 a = 2.
If a function is called more than once with the same arguments, you can eliminate the additional procedure calls by assigning the result to a temporary variable. For example, the statements: a = MIN(x,y) + 1.0 b = MIN(x,y) + 4.0 can be rewritten as: minval = MIN(x,y) a = minval + 1.0 b = minval + 4.0 The rewritten statements above are more e cient, but the readability is reduced. Combine DO Loops Combine adjacent DO loops that are executed the same number of times.
Eliminate Common Operations in Loops Minimize operations inside of a loop. If the result of an operation is the same throughout the loop, move the expression before or after the loops so the expression is only executed once. For example, the loop: 100 sum = 0.0 DO 100 i = 1,n sum = sum + value * a(i) can be replaced with: 100 Use Efficient IF Statements sum=0.
Avoid Formatted I/O When possible, use unformatted I/O. Formatted I/O requires costly conversions between binary and ASCII format. When using formatted I/O, put the format string in a separate FORMAT statement instead of using a variable. For example, use the statements: 20 instead of: WRITE (6,20) var FORMAT (F10.2) CHARACTER*7 a DATA a/'(F10.2)'/ WRITE (6,a) var Format speci ers contained in variables are not parsed when a program is compiled.
MPE/iX Run-Time Efficiency Topics To improve run-time e ciency on the MPE/iX operating system, do the following: When using the CHECK OVERFLOW compiler directive, specify $CHECK_OVERFLOW INTEGER OFF If left in the default state of ON, the directive generates extra code for each integer assignment for integer over ow checking. Use MPE/iX intrinsic I/O instead of the FORTRAN READ and WRITE statements. The FORTRAN statements generate several procedure calls for each statement.
Code Space Efficiency Use Function Subroutines Avoid Formatted I/O Use Character Substrings The suggestions below help to decrease the amount of space needed to store your program. Use function subprograms instead of statement functions because the code to execute statement functions is generated every place the function is called. Of course, you are sacri cing run-time e ciency because an extra procedure call is executed for the subprogram call.
The suggestions below help to decrease the amount of space needed to store data. Data Space Efficiency Eliminate Redundant or Unused Variables Eliminate redundant or unused variables. Redundant variables are de ned and used only one time. For example, in the statements: temp1 = a * 25.0 temp2 = b**3 answer = temp1 + temp2 the variables temp1 and temp2 are redundant. The three lines can be rewritten as: answer = a * 25.
Performance Tuning This section provides more information on how your program interacts with the MPE/iX operating system on the 900 HP Series 3000 computer and what can be done to optimize the relationship. Before reading this chapter, you should understand the memory model used by the compiler.
Grouping Related Routines 6-12 Writing Efficient Programs To understand how a program uses memory, you need to know how these areas are mapped into the physical segments of the 900 Series HP 3000 computer. The main memory is divided into page frames of a xed size, each of which can contain one virtual page. Data ow between main memory and external storage occurs in units of pages; the page size is 4K bytes. The stack and data areas belong to a separate virtual space from the code area.
to access data in di erent 16K segments. For example, if a is in location 0 while b is in location 16K+1 and the code states DO i = 1,10 a(i) = b(i) the compiler must switch dp to point to 16K to load the value of b. The compiler then must switch back to 0 to store to a(i). Grouping a and b could place b within the 16K range and eliminate the base register switching.
Shifting Data from the Data Area to the Stack Area Integer Overflow Checking 6-14 Writing Efficient Programs Another improvement in performance can be gained by shifting data from the data area to the stack area. In general, accessing data from the stack or code area takes one machine instruction, while accessing data from the data area requires two instructions. To shift data, use assignment statements if you do not require the data values to remain the same across routines.
Using the Optimizer Introduction to the Optimizer When to Use the Optimizer Invoking the Optimizer on MPE/iX The optimizer is an optional part of the compiler that modi es your program so that machine resources are used more e ciently, using less space and running faster. The optimizer consists of 12 modules: ve for level one optimization and seven for level two optimization.
The level one optimization modules are: Branch optimization Dead code elimination Faster register allocation Instruction scheduler Peephole optimization The examples in this section are shown at the source code level wherever possible; transformations that cannot be shown at the source level are shown in assembly language. Table 6-2 summarizes the assembly language routines. Level One Optimization Modules Table 6-2.
Branch Optimization Module The branch optimization module makes branch instruction sequences more e cient whenever possible.
Dead Code Elimination Module The dead code elimination module removes unreachable code that is never executed. For example, the code if (.FALSE.) then a=1 else a=2 endif becomes a=2 Faster Register Allocation Module The faster register allocation module, used with unoptimized code, analyzes register use faster than the advanced register allocator (a level two module).
Peephole Optimization Module The peephole optimization module is a machine-dependent module that makes a pass through an intermediate representation of the code applying patterns to a small window of code looking for optimization opportunities.
Advanced Register Allocation Module The advanced register allocation module performs some copy optimizations, as well as allocating registers. Before the register allocator is run, the instructions contain register numbers that do not correspond to actual registers. The register allocator assigns real registers to these instructions and removes unnecessary COPY instructions. For example, the following code shows the type of optimization the coloring register allocation module performs.
Common Subexpression Elimination The common subexpression elimination module identi es expressions that appear more than once and have the same result, computes the result, and substitutes the result for each occurrence of the expression. The types of subexpressions include instructions that load values from memory, as well as arithmetic evaluation.
Store/Copy Optimization Module Where possible, the store/copy optimization module substitutes registers for memory locations by replacing store instructions with copy instructions and deleting load instructions. For example, the following FORTRAN 77 code INTEGER FUNCTION i . . .
Optimizer Guidelines These guidelines will help you use the optimizer e ectively and write e cient HP FORTRAN 77 programs. 1. Where possible, expand procedures with fewer than ve lines in the program or convert them to macros. The optimizer makes better use of register variables if the procedures have fewer than 100 lines. If a loop only contains a procedure call, it is more e cient to put the loop in the procedure. 2. Make hash table sizes and eld sizes of variables in powers of two. 3.
function call is used to \lock" and \unlock" access to a shared variable. In this case, optimization is assumed to be correct.
OPTIMIZE Compiler Directive The OPTIMIZE compiler directive gives you the ability to give information about the program to the compiler. The OPTIMIZE directive controls which functions are optimized and which set of optimizations is performed. Some directives must be placed before the function to be optimized, while others can appear anywhere within the function.
LEVEL2_MIN LEVEL2_MAX ASSUME_NO_EXTERNAL_PARMS ASSUME_NO_FLOATING_INVARIANT ASSUME_NO_PARAMETER_OVERLAPS ASSUME_NO_SHARED_COMMON_PARMS ASSUME_NO_SIDE_EFFECTS ASSUME_PARM_TYPES_MATCHED LOOP_UNROLL 6-26 Writing Efficient Programs Speci es level 2 optimization with all the ASSUME settings OFF. Speci es level 2 optimization with all the ASSUME settings ON. Assumes that none of the parameters passed to the current procedure are from an external space, that is, di erent from the user's own data space.
There are ve levels of optimization: Level 0 Does no optimizing. This is obtained by specifying $OPTIMIZE OFF. Level 1 Optimizes only within each basic block. This is obtained by specifying $OPTIMIZE LEVEL1 ON. Level 2 minimum Optimizes within each procedure with no assumptions on interactions of procedures. That is, the compiler assumes nothing, making this the most conservative level 2 optimization. This level is obtained by specifying $OPTIMIZE LEVEL2_MIN ON within each procedure.
The ASSUME_NO_PARAMETER_OVERLAPS option should usually be set to ON. However, for the following code subroutine a(i,j,k) . . . END PROGRAM b CALL a(l,l,m) END the ASSUME_NO_PARAMETER_OVERLAPS option should not be set to ON because the rst two parameters passed to A are actually the same variable (that is, the parameters overlap).
However, for the following code PROGRAM a INTEGER i,j,k CALL s1(i) END SUBROUTINE s1(j) INTEGER j(3) j(1) = 1 END the ASSUME PARAMETERS MATCHED option has to be set to OFF before the call to s1 because the called subroutine s1 declares parameter j to be an integer array, which is not the same as an integer in the caller a. Notice that s1 is actually intended to change the contents of j(2), which is not i but the variable following i. However, what follows i is system dependent.
Default Location O.
static characteristics. A warning message will be issued when an uninitialized variable is detected.
Example C Start with minimum level 2 optimization. $OPTIMIZE LEVEL2_MIN PROGRAM FEQ7 INTEGER num(10), ans, calculate CHARACTER*2 option(10) C C For the next two calls, the parameter type declarations are the same in C the main program and the subroutine or function. Therefore, we can C further optimize the program by setting the following optimizer option.
C C C C C C C C END For the next subroutine, you know that the actual parameters passed to this subroutine are not overlapped with each other and not from an external space. Thus, you can leave the ASSUME_NO_PARAMETER_OVERLAPS and ASSUME_NO_EXTERNAL_PARMS settings ON. FUNCTION calculate(value,operation) INTEGER value(10),calculate,ans CHARACTER*2 operation(10) ans = 0 DO 10 i = 1,10 IF (operation(i).EQ.' ') GOTO 30 10 30 IF (operation(i).EQ.'**') THEN ans = ans ** value(i) ELSE IF (operation(i).EQ.
The ASSUME NO FLOATING INVARIANT option should be set to ON unless you need to turn it o for a speci c subprogram. The following example illustrates this option. C C C C C C C This program gets a divide by zero trap when compiled without ASSUME_NO_FLOATING_INVARIANT ON specified (the default). Because b/a is an invariant floating point operation (FLOP), it is moved out of the loop and executed whether the condition i.GT.10 is true or false.
2 Loop Unrolling 3 ON 7 6 OFF 7 6 7 $OPTIMIZE LOOP_UNROLL 6 6 COPIES = n 7 5 4 SIZE = n STATISTICS ON Turns on loop unrolling. ON is the default at level 2. OFF Turns o loop unrolling. COPIES = n Tells the compiler to unroll the loop n times. The default is four times. SIZE = n Tells the compiler to unroll the loops that have less than n operations. The default is 60 operations. STATISTICS Tells the compiler to give statistics about the unrolled loops.
Note 6-36 Writing Efficient Programs You can also use the LOOP UNROLL suboption on the $OPTIMIZE directive to change the DO LOOP constraints for unrolling dynamically: You can unroll a DO loop more than four times. You can force a DO loop to unroll despite its large size. You can nd the reason why a DO loop is not unrolled. The highest level of optimization must be on for LOOP UNROLL to work. Otherwise, LOOP UNROLL is ignored.
To unroll the loop two times instead of four times (which is the default), use $OPTIMIZE LOOP_UNROLL COPIES=2 To unroll a DO loop that is larger than the default, use $OPTIMIZE LOOP_UNROLL COPIES=2, SIZE=500 substituting an appropriate size for the digit 500. Example C Example to illustrate the use of LOOP_UNROLL $OPTIMIZE ON PROGRAM UNROLL_EXAMPLE DIMENSION A(10), B(10,10) DIMENSION X(10,10,10), Y(10,10,10), Z(10,10,10) ... ... C The inner loop has only one statement.
* Y(I,J,K) = Y(I,J,K) + A1*V1 + A2*V2 + A3*V3 + S*(Y(I+1,J,K)-2.0*Y(I,J,K)+Y(I-1,J,K)) * 30 40 Z(I,J,K) = Z(I,J,K) + A1*V1 + A2*V2 + A3*V3 + S*(Z(I+1,J,K)-2.0*Z(I,J,K)+Z(I-1,J,K)) CONTINUE CONTINUE C Change the options back to the default values. $OPTIMIZE LOOP_UNROLL COPIES=4, SIZE=60 . . . . STOP END What to Do If the Optimized Program Fails 6-38 Writing Efficient Programs Occasionally a program works di erently after optimization. If this happens: 1.
7 Programming for Portability This chapter describes how to port FORTRAN 77 programs from other systems onto HP systems, and how to make new programs easily transportable between HP systems. The suggestions in this chapter are derived from basic concepts of structured programming and good programming practices. However, because portability is the main topic of this chapter, some of the suggestions might not result in run-time e ciency.
Restricting Programs to the HP FORTRAN 77 Standard 7-2 Programming for Portability The rst step in writing portable FORTRAN 77 programs is to only use features of the language that are available on every system to which you port your programs. For HP systems, this feature set is de ned by the HP FORTRAN 77 standard, which fully implements the ANSI standard for FORTRAN as de ned by the ANSI X3.9-1978 documents.
Using Consistent Data Storage Use the LONG and SHORT Compiler Directives Because machine architectures di er between systems, the methods of storing data also di er. Default sizes for data types might also di er between HP and non-HP systems, resulting in the data storage accidentally overlapping. This creates a program that compiles and loads on both HP and non-HP systems without errors, but produces di erent results with the same input data.
Use Length Specifications in All Type Statements 7-4 Programming for Portability Not only should all the variables be explicitly declared, but their individual sizes should be de ned and documented. By declaring sizes, you avoid the possibility of di erent default sizes causing invalid run-time results and you ensure that the common and equivalence lengths are the same. Also, the data storage is well de ned, with the exact amount of variable storage speci ed in the declarations.
Declare All Variables Avoid Using the EQUIVALENCE Statement Declare Common Blocks the Same in Every Program Unit Implicit declaration of variables according to the standard HP FORTRAN 77 conventions (variables beginning with the letters I through N are INTEGER; the rest are REAL) causes a default data item's size to be assigned. In addition, implicit declarations are not documented, making modi cations di cult.
reference the le by using the INCLUDE statement or directive in every program unit that uses the common block. There is no chance of errors due to unmatched declarations if all program units that share a declaration le are recompiled whenever the declaration le changes. However, if all program units are not recompiled when their declaration le changes, di erences in the old and new common block de nitions might cause incorrect run-time results.
Initialize Data Before the Algorithm Begins Avoid Accessing the Representation of Logical Values Maintain Parameter Type and Length Consistency The initialization of memory locations varies between systems. Some systems check and initialize all allocated memory to a set value. Most systems leave the allocated memory in the same state as the previous program that used the memory. Therefore, to ensure storage portability, initialize all data before the actual algorithm begins.
storage allocation algorithm produces data areas that function identically. Alignment problems are avoided by a minimal use of the EQUIVALENCE statement. All common blocks of the same name should have the same internal structure. Data should be explicitly initialized. The internal representation of logical values should not be relied upon. Type and length consistency should be maintained for parameters and return values.
Writing Programs That Can Be Easily Modified If a program will be moved from one system to another, it is unlikely that the program will compile, link, load, and run correctly on the rst attempt. Therefore, an easily portable program should also be able to be easily changed. This section describes some guidelines for writing programs that can be easily modi ed. One way to write a program that can be easily modi ed is to space and indent statements.
It is not obvious what happens in the section or code, nor is it easy to see how the statements are nested. In contrast, the same program segment that indents at each nesting level and double-spaces between each logical section is shown below: J1 = 0 DO I=1,30 J1 = J1 + 1 IF (A(I,J1) .EQ. 0) THEN DO J=1,30 IF (J .NE. I) THEN A(I,J) = 1 ELSE A(I,J) = 0 ENDIF END DO ELSE IF (A(I,J1) .EQ. 1) THEN DO J=1,30 IF (J .NE.
However, the purpose of the program segment is not obvious. One way to make a program's function clear is to use meaningful variable names. The ANSI standard restricts variable names to six uppercase letters and numbers per variable name; using this limit, meaningful names can be constructed. HP FORTRAN 77 names can be any length (with a system-speci c limit on the number of signi cant characters) and can contain any combination of upper and lowercase letters, digits, and the underscore character.
Even though the readability of the example has improved by good programming practices, it is not obvious what kind of matrix transformation is taking place. To provide detailed information, use comments. A comment is identi ed by a C or * in column one. In addition, by appending an exclamation point ( ! ) to the end of a source or directive line, the remainder of the line is treated as a comment.
Now, with just a quick glance at the example, the program's function is obvious. However, be careful not to use too many comments and do not include comments that only repeat the actions of the code; these comments will obscure a program's function. Therefore, use a few, e ective comments instead of many unhelpful comments. A nal method of making a program readable and easy to change is to use named constants instead of numeric or string literals.
Adding PARAMETER statements and named constants to the example results in the following: PARAMETER (Lower_bound = 1, Upper_bound = 30) PARAMETER (Invalid_row = 999) PARAMETER (Repl_val_a = 0, Repl_val_b = 1) PARAMETER (Column_start = Lower_bound - 1) . . . Column_index = Column_start C Check each element along the principal diagonal. DO Row_index=Lower_bound,Upper_bound Column_index = Column_index + 1 !Avoids extra loop, retains clarity C C IF (Matrix(Row_index,Column_index) .EQ.
In summary, spacing and indenting statements make the program structure clearly visible. Adding meaningful variable names give general details about a program's function. When comments are e ectively used, important details become apparent. Using named constants improves documentation in the code and provides an easy way of changing values. If you apply the guidelines given above, your programs will be readable, easier to modify, and will be portable.
Avoiding Data Storage Inconsistencies Using Comments 7-16 The CHECK FORMAL PARM and CHECK ACTUAL PARM compiler directives help to avoid data storage inconsistencies between a program and its subprograms. If properly used, these directives supply parameter information to the system loader or Link Editor for checking inconsistencies in type, length, and number of parameters. Refer to the HP FORTRAN 77/iX Reference for a complete description.
Using Conditional Use the conditional compilation directives listed in table 8-1. Compilation Directives Table 7-1. Conditional Compilation Directives Directive $IF $ELSE $ENDIF $SET Description Conditionally compiles blocks of code. Used with the IF directive; marks the beginning of the ELSE block of code. Ends the IF directive. Assigns values to identi ers used in IF directives.
For example, the partial program below uses the system intrinsics if the program is run on an MPE/iX system and uses FORTRAN I/O for portable code. PROGRAM sysmpeix $SET (os_mpe_ix = .TRUE.) CHARACTER buffer(80) $IF (os_mpe_ix) SYSTEM INTRINSIC FREAD, FWRITE $ENDIF . . .
Resolving Incompatibilities between MPE V and MPE/iX: the HP3000 16 Directive This section describes how to use the HP3000 16 compiler directive. This directive helps resolve some of the incompatibilities between the MPE V and MPE/iX operating systems and architectures.
Do not use the HP3000 16 compiler directive if the application that is ported from MPE V to MPE/iX is not a ected by any of the above incompatibilities. Likewise, if the application has only one of the incompatibilities, specify only the appropriate option in the directive. Table 7-2 summarizes the options. Table 7-2. HP3000 16 Directive Options Option ON OFF ALIGNMENT REALS STRING MOVE Description Turns on all three options (ALIGNMENT, REALS, and STRING MOVE).
The ALIGNMENT Option MPE V aligns noncharacter data on 16-bit boundaries and character data on 8-bit boundaries. MPE/iX aligns data on 8-, 16-, 32-, and 64-bit boundaries, depending on the data type. Table 7-3 shows the corresponding data alignments. Table 7-3.
Figure 7-1 shows how the structure is stored in memory on the MPE V system. Figure 7-1. MPE V Structure Figure 7-2 shows how the structure is stored in memory on the MPE/iX system. Figure 7-2.
Because the INTEGER*2 (2-byte) and INTEGER*4 (4-byte) integers are stored on 16-bit boundaries on the MPE V system, the above EQUIVALENCE statement is not a problem (as shown in Figure 7-1). However, on MPE/iX, the compiler will have trouble aligning the variable var1 on the array int_array(2) because var1 should be 32-bit aligned and int_array(2) is on a 16-bit boundary. At this point, the compiler shifts the array int_array 16 bits so that it can align the variable var1 on a 32-bit boundary.
The REALS Option MPE/iX uses the IEEE oating point standard for representing REAL*4, REAL*8, REAL*16, COMPLEX*8, and COMPLEX*16 types. MPE V uses proprietary HP3000 oating point to represent these types. The REALS option reads, writes, and executes all oating point numbers in the proprietary HP3000 oating point format. Use the REALS option if your program accesses a binary at le or accesses a database that contains proprietary HP3000 oating point. This option is not necessary if the at les are ASCII les.
The STRING MOVE Option The STRING MOVE option should only be used when the application assumes that overlapping character substring moves have a ripple e ect, as on MPE V. MPE/iX does not ripple the overlapping character substring moves and therefore increases performance on character moves. For example, the result of the program fragment character ch*10 ch(1:1) = '* ch(2:10) = ch(1:9) ' depends on the operating system. On MPE V, the character string ch is lled with asterisks (*).
8 Interfacing with Other Languages This chapter describes how to call routines written in HP Pascal/iX, HP COBOL/iX, or HP C/iX from an HP FORTRAN 77/iX program, and how to call an HP FORTRAN 77/iX subroutine or function from HP Pascal/iX, HP COBOL/iX, or HP C/iX. If you call other languages from HP FORTRAN 77/iX, the actual parameters of the internal procedure or function must match the formal parameters of the external procedure or function.
HP Pascal/iX is the ANSI standard version of Pascal for the HP 3000 Series 900 computer. An HP Pascal/iX procedure or function can be called from an HP FORTRAN 77/iX program and an HP FORTRAN 77/iX program can call an HP Pascal/iX procedure or function if the data types of the parameters match (see Table 8-1). The language code of the ALIAS compiler directive should be used for correctly passing parameters. HP Pascal/iX Table 8-1.
Calling HP Pascal/iX from HP FORTRAN 77/iX HP FORTRAN 77/iX cannot pass arrays by value, so you cannot call an HP Pascal/iX routine with a value parameter of a type corresponding to an HP FORTRAN 77/iX array type. You must use the %VAL parameter of the ALIAS compiler directive for other types of HP Pascal/iX value parameters.
External HP Pascal/iX procedure: $SUBPROGRAM$ PROGRAM pascal; TYPE charstr = PACKED ARRAY[1..30] OF CHAR; { Turn parameter checking off because HP Pascal/iX generates different parameter type check values than HP FORTRAN 77/iX.
Calling HP FORTRAN 77/iX from HP Pascal/iX An HP FORTRAN 77/iX subroutine or function can be called from an HP Pascal/iX program if the data types of the parameters match (see Table 8-1). However, be careful when passing character strings. HP FORTRAN 77/iX expects an additional word that describes the maximum length of the string, while PAC's (packed array of char ) in Pascal do not.
WRITELN; WRITELN(str); END.
HP FORTRAN 77/iX subroutine: c c c c c SUBROUTINE fortprog(str,cur_len) The formal parameters are the character string and the current length of the string; the maximum length of the character string is a hidden parameter that HP FORTRAN 77/iX uses.
The data types of HP FORTRAN 77/iX and HP COBOL II/iX di er. Numeric HP COBOL II/iX data types are binary packed-decimal or in ASCII format (see Table 8-2). However, by taking the size and the format into consideration, you can successfully match HP FORTRAN 77/iX and HP COBOL II/iX types. HP COBOL II/iX Table 8-2.
Table 8-3 shows examples of possible matches between HP COBOL II/iX and HP FORTRAN 77/iX types. Table 8-3. HP COBOL II/iX and HP FORTRAN 77/iX Data Types HP COBOL II/iX Type HP FORTRAN 77/iX Type PIC X(N) CHARACTER*n PIC S9(01)-S9(04) COMP INTEGER*2 {-9999..9999} PIC S9(05)-S9(09) COMP INTEGER*4 {999,999,999..999,999,999} PIC S9(10)-S9(18) COMP INTEGER*4 varname(2) The HP COBOL II/iX types 01 and 77 always start on word boundaries.
Calling HP COBOL II/iX from HP FORTRAN 77/iX HP COBOL II/iX expects parameters to be passed by reference. When passing character data to an HP COBOL II/iX routine, the ALIAS compiler directive must indicate that the routine language is HP COBOL II/iX, so only the string address is passed and not the additional length.
Calling HP FORTRAN 77/iX from HP COBOL II/iX The GIVING phrase must be used when calling an HP FORTRAN 77/iX function from HP COBOL II/iX. Example 1 HP COBOL II/iX program that calls an HP FORTRAN 77/iX function: 001000 002000 003000 004000 005000 006000 007000 008000 009000 010000 011000 012000 013000 014000 015000 016000 017000 018000 019000 020000 021000 022000 IDENTIFICATION DIVISION. PROGRAM-ID. CALLFTN. DATA DIVISION. WORKING-STORAGE SECTION. 01 TABLE-INIT.
023000 PROCEDURE DIVISION. 024000 P1. 025000**************************************************************** 026000* Call FORTRAN subroutine "LARGER" to find the largest element * 027000* in a table on "LEN" elements. * 028000**************************************************************** 029000 030000 MOVE 8 TO LEN. 031000 CALL "LARGER" USING TABLE-1, LEN GIVING LARGEST-VALUE. 032000 DISPLAY LARGEST-VALUE " IS THE LARGEST VALUE IN THE TABLE".
HP FORTRAN 77/iX function: C C C C C C C C INTEGER*4 FUNCTION LARGER(A,L) INTEGER*4 A(8) INTEGER*4 LARGST,L THIS SUBROUTINE FINDS THE LARGEST VALUE IN AN ARRAY OF 'L' INTEGERS. LARGST = A(1) DO 100 I = 2,L IF (LARGST .GT.
Example 2 HP COBOL II/iX program that calls an HP FORTRAN 77/iX function: IDENTIFICATION DIVISION. PROGRAM-ID. CALLFTN2. DATA DIVISION. WORKING-STORAGE SECTION. 01 INT-1 PIC S9(4) COMP SYNC VALUE 13. 01 INT-2 PIC S9(4) COMP SYNC. 01 STRING-1 PIC X(10) VALUE "0123456789". PROCEDURE DIVISION. P1. CALL "FUNC1" USING INT-1,@STRING-1 GIVING INT-2. DISPLAY STRING-1. DISPLAY INT-2.
HP C/iX HP C/iX, when invoked in ANSI mode, is a conforming implementation of ANSI C, as speci ed by American National Standard X3.159-1989. It runs on the HP 3000 Series 900 computer. An HP C/iX procedure or function can be called from an HP FORTRAN 77/iX program and an HP FORTRAN 77/iX program can call an HP C/iX procedure or function if the data types of the parameters match (see the table below). The ALIAS compiler directive should be used for correctly passing parameters. Table 8-4.
HP FORTRAN 77/iX and HP C/iX Types (Continued) HP C/iX Type HP FORTRAN 77/iX Type INTEGER*4 Not available.
Notes on HP FORTRAN 77/iX and HP C/iX Types 1. The FORTRAN 77 type of COMPLEX or COMPLEX*8 is equivalent to the following HP C/iX structure: struct complex { float real_part; float imag_part; }; 2. The FORTRAN 77 type of DOUBLE COMPLEX or COMPLEX*16 is equivalent to the following HP C/iX structure: struct complex { double real_part; double imag_part; }; 3.
Parameter Passing between HP FORTRAN 77 and HP C The major di erence is that FORTRAN and C pass parameters di erently|FORTRAN by reference and C by value. This means that all actual parameters in an HP C call to an HP FORTRAN 77 routine must be pointers or variables pre xed with the unary address-of operator &.
This example shows passing a character string from a FORTRAN program to a C function. The function returns the number of characters in the string before a space. Otherwise it returns the maximum string length.
MPE/iX system intrinsics are procedures and functions written in HP Pascal/iX. The system intrinsics handle individual programming operations and are invoked by procedure or function calls. This chapter describes how to de ne and call the system intrinsics. FORTRAN 77 intrinsic functions are part of the FORTRAN 77 library in acordance with the ANSI and MIL-STD-1753 standards. The FORTRAN 77 intrinsics do not have to be de ned as system intrinsics.
Matching Actual and Formal Parameters When a procedure or function is identi ed as an intrinsic, the formal parameters do not have to be listed. When an intrinsic is called, the compiler checks the SYSINTR le to compare the actual parameters with the formal parameters. Table 8-5 shows how HP FORTRAN 77/iX actual parameters are matched to the intrinsic formal parameters. Table 8-5.
Example PROGRAM intrinsic_example IMPLICIT NONE SYSTEM INTRINSIC fopen,read,fgetinfo,fclose,printfileinfo SYSTEM INTRINSIC fcontrol CHARACTER*36 filename,cmd,fname CHARACTER tab*10 INTEGER*2 ifnum,recsize INTEGER*2 tlen,i INTEGER*4 eof 1 2 3 4 FORMAT FORMAT FORMAT FORMAT (1X) (A,'Input file > ') (1X,'The file ',A8,' has record length of ',I3) (1X,'and contains ',I3,' records.
Some MPE/iX intrinsics are OPTION EXTENSIBLE, which means that a partial formal parameter list can be passed to the intrinsic. The example above passed a partial parameter list to FOPEN and FGETINFO. The MPE/iX intrinsic FGETINFO is an option extensible intrinsic with up to 20 parameters. In the example above, the statement CALL FGETINFO(ifnum,,,,recsize,,,,,,eof) does not use the second through the fourth or the sixth through the tenth parameters.
9 Debugging FORTRAN 77 Programs HP FORTRAN 77/iX programs can be symbolically debugged using one of the following: xdb symbolic debugger HP Toolset/iX This chapter describes both methods of debugging. Using xdb The symbolic debugger xdb is a powerful debugging facility. Refer to the HP Symbolic Debugger/iX User's Guide for a complete description of xdb.
The symbolic debugger (xdb) is the primary tool for debugging a program that does not execute properly. The debugger supports debugging capabilities on C, FORTRAN, and Pascal programs. In addition to the symbolic debugger, HP FORTRAN 77 o ers a range checking option for detecting run-time errors, as described earlier in this chapter. To analyze a program, the debugger uses the executable le and related source les. The debugger has many commands for viewing and manipulating your program.
The Strategy Program Requirement When your program does not execute properly, use the following strategy to locate and correct any problems: 1. Invoke the symbolic debugger. The result is that you create a debugging environment in which you can now execute your program. 2. Execute the program in the debugging environment and then use the debugger commands to locate the execution bugs. 3.
Linker and Debugger Interaction Invoking the Debugger You should be aware that using the symbolic debugger greatly increases the size of your program (often by a factor of two or three) because of the tables it creates.
Exiting the Debugger To exit the debugger, type q You are prompted for con rmation that you really want to exit from xdb. This is a safeguard in case you accidentally type the letter q. Executing Your Program To execute your program in the debugger environment, type r The r command allows you to specify any arguments that your program needs.
Viewing the Source File The xdb debugger has several commands that you can use to look at your program source le while you are in the debugger environment. The debugger keeps track of the last le, routine, and line viewed (referred to as the current le , current routine , and current line ). The debugger uses the last location viewed to determine the e ect of several of its commands. The last viewed current values are not the same as the location of the next line to be executed in the program.
The Window Command The window (w) command changes the size of the source window to a new value of n ; n can range from 1 to 20. Changing the size of the source window also changes the size of the command window. The form of the command is wn The default value for n is two-thirds the length of the screen, minus one. For most HP terminals, n is 15. The Move Command The commands for moving around in a le, relative to the current line, are + and -.
the listing is for the routine in your program called routine .
Finding a Variable's Value You can nd the value of a variable (or expression) with the p command: p name The debugger searches for a local variable or parameter called name in the current routine. The following example shows the command used with an expression: p 1+2 The response is 3. To nd the value of a local variable or parameter in a routine other than the current routine, type p routine:name which gives you the value of variable name during the most recent execution of routine .
Setting Breakpoints The command b sets breakpoints. It has many variations, but the simplest one has the form b This causes a breakpoint to be set at the current line of the current le and routine or the rst executable statement following the current line. Using the commands mentioned earlier in \Viewing the Source File", move to the location in your source le where you want the breakpoint. The le, routine, and line that you move to becomes the new current le, routine, and line.
Deleting Breakpoints To delete breakpoints from your program, use the db or db* command. The db command removes one breakpoint, while db* removes all breakpoints. By typing db you remove any breakpoint set at the current line. If there is no breakpoint to remove, you receive a listing of all of the breakpoints in your program. The lines of the listing are in the form number routine:line count commands number is an integer label that the debugger assigns to each breakpoint.
Single Step Commands The commands for specifying single step execution of your program are the s and S commands. Typing s executes one statement and suspends the program. Typing sn executes n statements before the program suspends. The default value for n is 1. The S command also allows single stepping through a program. When routine calls are reached in the currently executing routine, they are treated as statements and are executed.
Using HP Toolset/iX Compiling Programs for HP Toolset/iX HP Toolset/iX performs the following: Sets breakpoints Interactively displays and modi es the values of variables Displays subroutines or functions currently called Traces each subroutine or function as it executes Traces variables as they are modi ed by the program To symbolically debug, you must compile your program with the SYMDEBUG compiler directive, which instructs the compiler to generate additional information needed by HP Toolset/iX.
When to Use HP Toolset/iX Running a Program Using the symbolic debugger increases the size of your program (often by a factor of two or three). When your program executes correctly and you no longer need the symbolic debugger, remove the compiler option, recompile the source les, and relink the object les. Without the debugging information, the program occupies less space, allowing it to link and execute faster.
AT func2#20 Note Tracing Names You cannot directly set a breakpoint at FORTRAN entry statements. However, using the AT NEXT command stops your program from entering any subroutine. Therefore, the AT NEXT command allows you to stop at entry statements. The CALLS command displays the names of the subroutines and functions that are currently executing. The trace begins with the most recently called subroutine or function. The statement following the call is also displayed.
Clearing Breakpoints The CLEAR command removes breakpoints from your program. Syntax 2 CL EAR 9 8 location = < 3 : next ALL ; Example The following statement clears the breakpoint at the location sub1: CL sub1 Displaying Variables The DISPLAY command causes the current contents of the speci ed FORTRAN variable (data item) to be displayed on your terminal in octal, integer, character, or hexadecimal format. By default, the variables are displayed in the format most appropriate for the data type.
The following is output using DISPLAY commands: >>DISPLAY long_integer_var --> Stmt #101: Var: LONG_INTEGER_VAR = 1234567890 >>DIS real_var --> Stmt #101: Var: REAL_VAR = 0.123456E38 >>DIS double_complex_var --> Stmt #101: Var: DOUBLE_COMPLEX_VAR = (8.2E308,7.1E308) >>DIS short_logical_var --> Stmt #101: Var: SHORT_LOGICAL_VAR = .TRUE.
Modifying Variables The MOVE command transfers the value of a literal, a gurative constant (such as .TRUE. and .FALSE.), or a variable, to another variable.
Redoing a Command The REDO command allows you to correct and re-execute the last command or command list. The command editing is performed with EDITOR program operators. Syntax 2 RED O 3 Example >>MVE 30 TO long_integer_var **Undefined TOOLSET/iX command keyword.
Using the Trace Facilities The TRACE command displays each subroutine or function name as it is executed. An identifying message is displayed at the start and end of each subroutine or function. Syntax 2 T RACE 32 OFF 3 The DATATRACE command monitors the value of a data item. If the value changes, a message containing the location and the new value is displayed.
Index 9 A 900 Series HP 3000 architecture, 1-11 ACCESS='DIRECT', 4-6 accessing disk, 3-1 accessing MPE/iX debug, 9-20 accessing the representation of logical values, 7-7 ACCESS='SEQUENTIAL', 4-5 ACCESS='SEQUENTIAL' option, 3-2 actual arguments in subprograms, 5-18 in subroutines, 5-4 actual parameters, 8-21 addressing mode, 1-3 adjustable dimensions, 5-28 A format descriptor, 2-21 ALIAS compiler directive, 8-1 alignment of data, 1-2 ALIGNMENT option, 7-21 alternate returns from a subroutine, 5-5 ANSI comp
B C Index-2 BACKSPACE statement, 3-29, 4-5, 4-13 blank common blocks, 5-36 blanks in the input eld BN descriptor, 2-52 BZ descriptor, 2-52 BLANK speci er, 3-13 BLOCK DATA statement, 5-41 block data subprograms, 5-41 blocking factor, 4-9 BN edit descriptor, 2-52 breakpoints clearing, 9-16 displaying, 9-19 setting, 9-14 bytes, returning number of, 2-49 BZ edit descriptor, 2-54 Calling HP COBOL II/iX from HP FORTRAN 77/iX, 8-10 Calling HP FORTRAN 77/iX from HP COBOL II/iX, 8-11 Calling HP FORTRAN 77/iX from
colon edit descriptor, 2-50 comments, 7-16 common blocks, 1-12 blank common, 5-36 declaring, 7-5 description, 5-36 EQUIVALENCE statement, 1-9 labeled common, 5-39 common blocks in memory, 1-12 COMMON statement, 5-36 common subexpression elimination module, 6-21 compiler directive HP3000 16, 7-19 STANDARD LEVEL, 7-15 compiler directives INCLUDE, 7-5 LONG, 7-3 NOSTANDARD, 2-29 SHORT, 7-3 compiler library, 4-7 compile-time e ciency, 6-2 complex format descriptors, 2-17 conditional compiler directives, 7-17 con
reading and writing, 3-15 direct access option, 4-6 directives OPTIMIZE, 6-25 direct mode of addressing, 1-3 disconnecting les, 3-1 disk les, 3-1, 4-8 DISPLAY command, 9-16 displaying breakpoints, 9-19 displaying functions, 9-20 displaying names, 9-15 displaying subroutines, 9-20 displaying variables, 9-16 DO loop, implied, 2-56 DO loops, 6-8 DO WHILE loops, 6-8 dummy arguments in subprograms, 5-18 in subroutines, 5-2 E Index-4 $ edit descriptor, 2-38 / edit descriptor, 2-38 : edit descriptor, 2-50 edit d
ENDIF compiler directive, 7-17 ending execution, 9-20 end-of- le record, 3-12, 3-34 END RUN command, 9-20 END statement, 4-7 description, 5-10 subroutines, 5-3 entries into subprograms, 5-32 ENTRY statement, 5-32 EOF, 4-8 equivalence array elements, 1-4 character variables, 1-8 EQUIVALENCE statement array elements, 1-4 arrays with di erent dimensions, 1-7 avoid using, 7-5 character variables, 1-8 common blocks, 1-9 data alignment, 1-10 data storage, 1-4 description, 1-4 multi-dimensioned arrays, 1-6 errors,
le handling procedures, 4-10 le handling statement examples, 3-31 le operations, 4-1 le pointer, 3-1, 3-29 le positioning BACKSPACE statement, 3-29 ENDFILE statement, 3-29 examples, 3-30 REWIND statement, 3-29 le properties, 3-2 les appending to, 3-11 creating, 3-6 direct access, 3-14 formatted, 3-24 indexed sequential, 3-18 INQUIRE statement, 3-26 internal, 3-34 ISAM, 3-18 reading, 3-9 sequential, 3-12 unformatted, 3-24 les,creating, 4-4 le size, 4-1 FILESIZE, 4-1 les,prede ned, 4-2 FNUM procedure, 4-12 FO
FSET procedure, 4-10 FTN05, 4-2 FTN06, 4-2 functions, 5-1 categories, 5-9 description, 5-9 intrinsic, 5-16 statement, 5-15 subprograms, 5-9 user-de ned, 5-10 FUNCTION statement, 5-9, 5-12 FWRITE, 4-8 FWRITEDIR, 4-5 G H I G format descriptor, 2-17 GIVING phrase, 8-11 grouping related routines, 6-12 H edit descriptor, 2-44 hollerith edit descriptor, 2-44 HP3000 16 compiler directive, 6-8 description, 7-19 options, 7-20 HP COBOL II/iX, 8-8 HP Pascal/iX, 8-2 HP Toolset/iX description, 9-1 exiting, 9-20 invok
O descriptor, 2-12 output eld, 2-15 Z descriptor, 2-12 interfacing with other languages, 8-1 internal les description, 3-34 reading, 3-34 writing, 3-36 intrinsic functions, 5-16 intrinsic I/O, 6-8 intrinsics,system, 8-20 invoking subroutines, 5-4 I/O errors, 4-7 I/O library, 4-8 IOSTAT speci er, 3-5 IOSTAT speci ers, 4-7 ISAM, 3-18 K L Index-8 K format descriptor, 2-12 labeled common blocks, 5-39 languages,interfacing with, 8-1 length speci cations, 7-4 L format descriptor, 2-30 line printer, 4-8 link ed
M N machine instructions, 1-11 magnetic tapes, 4-9 main memory, 6-12 maintaining parameter type and length consistency, 7-7 memory area assignment, 1-12 memory areas, 1-11 memory areas, summary, 1-13 memory data areas, 3-34 modi able programs, 7-9 modifying variables, 9-18 monetary data eld, 2-34 monetary format descriptor, 2-34 MOVE command, 9-18 MPE/iX debug, 9-20 MPE/iX operating system, 4-7 MPE/iX run-time e ciency, 6-8 MPE V operating system, 7-19 MPE V system, 7-22 multiple entries into subprograms,
O P Index-10 OFF option, 7-20 O format descriptor, 2-12 OLD les, 4-4 old status option, 4-4 ON option, 7-20 OPEN statement ACCESS='SEQUENTIAL' option, 3-2 appending to a le, 3-11 connecting les, 3-1 creating les, 4-4 description, 4-1 ERR speci er, 3-3 FORM='FORMATTED' option, 3-2 IOSTAT speci er, 3-5 options, 4-1 processor, 4-1 reporting errors, 3-2 STATUS='OLD' status, 3-9 STATUS speci er, 3-3 STATUS='UNKNOWN' option, 3-2 optimization techniques, 6-1 optimization, branch, 6-17 optimization, level one, 6
SS edit descriptor, 2-49 portable programs, 7-1 positioning the le pointer, 3-29 preconnected units, 2-1 prede ned les, 4-2 prede ned units, 4-2 prespacing mode, 4-8 PRINT statement formatted, 2-7 programming for portability, 7-1 program,terminating, 4-7 program unit, 5-5 proprietary oating point data, 7-20 Q R Q edit descriptor, 2-49 quotation mark edit descriptor, 2-43 reading an existing le, 3-9 READ statement, 6-8 formatted input, 2-6 list-directed, 2-1 unformatted, 3-23 real format descriptors, 2-17
S Index-12 saved variables in memory, 1-12 SAVE statement, 1-12, 5-43 scale factors, 2-44 scratch status option, 4-4 S edit descriptor, 2-49 sequential access, 4-5 sequential access les, 3-12 SET compiler directive, 7-17 setting breakpoints, 9-14 setting up a workspace, 9-13 setting up for symbolic debug, 9-13 shifting data, 6-14 SHORT compiler directive, 4-14, 7-3 SHOW DEBUG command, 9-19 slash edit descriptor, 2-38 slash in input eld, 2-2 SP edit descriptor, 2-49 SS edit descriptor, 2-49 stack area, 1-1
subroutines alternate returns, 5-5 common block, 5-36 description, 5-2 invoking, 5-4 recursive, 5-2 structure, 5-2 SUBROUTINE statement, 5-2 subsystems, 8-20 summary of the memory areas, 1-13 symbolic debugger additional capabilities, 9-12 breakpoints, 9-9 controlling execution, 9-9 delete breakpoints, 9-11 description, 9-1 execute program, 9-5 execution control, 9-9 exiting, 9-5 invocation, 9-4 listing variables, 9-7 move command, 9-7 program requirement, 9-3 recover from breakpoints, 9-10 remove debugging
exiting, 9-20 invoking, 9-13 when to use, 9-14 TRACE command, 9-20 trace facilities DATATRACE command, 9-20 RETRACE command, 9-20 TRACE command, 9-20 tracing names, 9-15 transfering values, 9-18 transportable programs, 7-1 TR edit descriptor, 2-42 U V W X Z Index-14 unformatted les, 3-24 unformatted form option, 4-5 unformatted input, 3-23 unformatted I/O, 3-23 unformatted output, 3-23 unformatted READ statement, 3-23 unformatted WRITE statement, 3-23 uninitialized local variables, 1-12 uninitialized