HP Fortran for OpenVMS
Language Reference Manual


Previous Contents Index


Chapter 7
Execution Control

This chapter describes:

7.1 Overview

A program normally executes statements in the order in which they are written. Executable control constructs and statements modify this normal execution by transferring control to another statement in the program, or by selecting blocks (groups) of constructs and statements for execution or repetition.

In Fortran 95/90, control constructs (CASE, DO, and IF) can be named. The name must be a unique identifier in the scoping unit, and must appear on the initial line and terminal line of the construct. On the initial line, the name is separated from the statement keyword by a colon (:).

A block can contain any executable Fortran statement except an END statement. You can transfer control out of a block, but you cannot transfer control into another block.

DO loops cannot partially overlap blocks. The DO statement and its terminal statement must appear together in a statement block.

7.2 Branch Statements

Branching affects the normal execution sequence by transferring control to a labeled statement in the same scoping unit. The transfer statement is called the branch statement, while the statement to which the transfer is made is called the branch target statement.

Any executable statement can be a branch target statement, except for the following:

Certain restrictions apply to the following statements:
Statement Restriction
DO terminal statement The branch must be taken from within its nonblock DO construct. 1
END DO The branch must be taken from within its block DO construct.
END IF The branch should be taken from within its IF construct. 2
END SELECT The branch must be taken from within its CASE construct.


1If the terminal statement is shared by more than one nonblock DO construct, the branch can only be taken from within the innermost DO construct.
2You can branch to an END IF statement from outside the IF construct; this is a deleted feature in Fortran 95. HP Fortran fully supports features deleted in Fortran 95.

The following branch statements are described in this section:

For More Information:

7.2.1 Unconditional GO TO Statement

The unconditional GO TO statement transfers control to the same branch target statement every time it executes. It takes the following form:

  • GO TO label

label

Is the label of a valid branch target statement in the same scoping unit as the GO TO statement.

The unconditional GO TO statement transfers control to the branch target statement identified by the specified label.

The following are examples of GO TO statements:


GO TO 7734 
GO TO 99999 

7.2.2 Computed GO TO Statement

The computed GO TO statement transfers control to one of a set of labeled branch target statements based on the value of an expression. It is an obsolescent feature in Fortran 95.

The computed GO TO statement takes the following form:

  • GO TO (label-list)[,] expr

label-list

Is a list of labels (separated by commas) of valid branch target statements in the same scoping unit as the computed GO TO statement. (Also called the transfer list.) The same label can appear more than once in this list.

expr

Is a scalar numeric expression in the range 1 to n, where n is the number of statement labels in label-list. If necessary, it is converted to integer data type.

Rules and Behavior

When the computed GO TO statement is executed, the expression is evaluated first. The value of the expression represents the ordinal position of a label in the associated list of labels. Control is transferred to the statement identified by the label. For example, if the list contains (30,20,30,40) and the value of the expression is 2, control is transferred to the statement identified with label 20.

If the value of the expression is less than 1 or greater than the number of labels in the list, control is transferred to the next executable statement or construct following the computed GO TO statement.

Examples

The following example shows valid computed GO TO statements:


GO TO (12,24,36), INDEX 
GO TO (320,330,340,350,360), SITU(J,K) + 1 

7.2.3 ASSIGN and Assigned GO TO Statements

The ASSIGN statement assigns a label to an integer variable. Subsequently, this variable can be used as a branch target statement by an assigned GO TO statement or as a format specifier in a formatted input/output statement.

The ASSIGN and assigned GO TO statements have been deleted in Fortran 95; they were obsolescent features in Fortran 90. HP Fortran fully supports features deleted in Fortran 95.

For More Information:

On obsolescent features in Fortran 95 and Fortran 90, as well as features deleted in Fortran 95, see Appendix A.

7.2.3.1 ASSIGN Statement

The ASSIGN statement assigns a statement label value to an integer variable. It takes the following form:

  • ASSIGN label TO var

label

Is the label of a branch target or FORMAT statement in the same scoping unit as the ASSIGN statement.

var

Is a scalar integer variable.

Rules and Behavior

When an ASSIGN statement is executed, the statement label is assigned to the integer variable. The variable is then undefined as an integer variable and can only be used as a label (unless it is later redefined with an integer value).

The ASSIGN statement must be executed before the statements in which the assigned variable is used.

Examples

The following example shows ASSIGN statements:


INTEGER ERROR 
... 
ASSIGN 10 TO NSTART 
ASSIGN 99999 TO KSTOP 
ASSIGN 250 TO ERROR   

Note that NSTART and KSTOP are integer variables implicitly, but ERROR must be previously declared as an integer variable.

The following statement associates the variable NUMBER with the statement label 100:


ASSIGN 100 TO NUMBER 

If an arithmetic operation is subsequently performed on variable NUMBER (such as follows), the run-time behavior is unpredictable:


NUMBER = NUMBER + 1 

To return NUMBER to the status of an integer variable, you can use the following statement:


NUMBER = 10 

This statement dissociates NUMBER from statement 100 and assigns it an integer value of 10. Once NUMBER is returned to its integer variable status, it can no longer be used in an assigned GO TO statement.

7.2.3.2 Assigned GO TO Statement

The assigned GO TO statement transfers control to the statement whose label was most recently assigned to a variable. The assigned GO TO statement takes the following form:

  • GO TO var [[,] (label-list)]

var

Is a scalar integer variable.

label-list

Is a list of labels (separated by commas) of valid branch target statements in the same scoping unit as the assigned GO TO statement. The same label can appear more than once in this list.

Rules and Behavior

The variable must have a statement label value assigned to it by an ASSIGN statement (not an arithmetic assignment statement) before the GO TO statement is executed.

If a list of labels appears, the statement label assigned to the variable must be one of the labels in the list.

Both the assigned GO TO statement and its associated ASSIGN statement must be in the same scoping unit.

Examples

The following example is equivalent to GO TO 200 :


ASSIGN 200 TO IGO 
GO TO IGO 

The following example is equivalent to GO TO 450 :


ASSIGN 450 TO IBEG 
GO TO IBEG, (300,450,1000,25) 

The following example shows an invalid use of an assigned variable:


ASSIGN 10 TO I 
J = I 
GO TO J 

In this case, variable J is not the variable assigned to, so it cannot be used in the assigned GO TO statement.

7.2.4 Arithmetic IF Statement

The arithmetic IF statement conditionally transfers control to one of three statements, based on the value of an arithmetic expression. It is an obsolescent feature in Fortran 95 and Fortran 90.

The arithmetic IF statement takes the following form:

  • IF (expr) label1, label2, label3

expr

Is a scalar numeric expression of type integer or real (enclosed in parentheses).

label1, label2, label3

Are the labels of valid branch target statements that are in the same scoping unit as the arithmetic IF statement.

Rules and Behavior

All three labels are required, but they do not need to refer to three different statements. The same label can appear more than once in the same arithmetic IF statement.

During execution, the expression is evaluated first. Depending on the value of the expression, control is then transferred as follows:
If the Value of expr is: Control Transfers To:
Less than 0 Statement label1
Equal to 0 Statement label2
Greater than 0 Statement label3

Examples

The following example transfers control to statement 50 if the real variable THETA is less than or equal to the real variable CHI. Control passes to statement 100 only if THETA is greater than CHI.


IF (THETA-CHI) 50,50,100 

The following example transfers control to statement 40 if the value of the integer variable NUMBER is even. It transfers control to statement 20 if the value is odd.


IF (NUMBER / 2*2 - NUMBER) 20,40,20 

For More Information:

On obsolescent features in Fortran 95 and Fortran 90, see Appendix A.

7.3 CALL Statement

The CALL statement transfers control to a subroutine subprogram. It takes the following form:

  • CALL sub [([a-arg [,a-arg]...]) ]

sub

Is the name of the subroutine subprogram or other external procedure, or a dummy argument associated with a subroutine subprogram or other external procedure.

a-arg

Is an actual argument optionally preceded by [keyword=], where keyword is the name of a dummy argument in the explicit interface for the subroutine. The keyword is assigned a value when the procedure is invoked.

Each actual argument must be a variable, an expression, the name of a procedure, or an alternate return specifier. (It must not be the name of an internal procedure, statement function, or the generic name of a procedure.)

An alternate return specifier is an asterisk (*), or ampersand (&) followed by the label of an executable branch target statement in the same scoping unit as the CALL statement. (An alternate return is an obsolescent feature in Fortran 95 and Fortran 90.)

Rules and Behavior

When the CALL statement is executed, any expressions in the actual argument list are evaluated, then control is passed to the first executable statement or construct in the subroutine. When the subroutine finishes executing, control returns to the next executable statement following the CALL statement, or to a statement identified by an alternate return label (if any).

If an argument list appears, each actual argument is associated with the corresponding dummy argument by its position in the argument list or by the name of its keyword. The arguments must agree in type and kind parameters.

If positional arguments and argument keywords are specified, the argument keywords must appear last in the actual argument list.

If a dummy argument is optional, the actual argument can be omitted.

An actual argument associated with a dummy procedure must be the specific name of a procedure, or be another dummy procedure. Certain specific intrinsic function names must not be used as actual arguments (see Table 9-1).

You can use a CALL statement to invoke a function as long as the function is not one of the following types:

Examples

The following example shows valid CALL statements:


CALL CURVE(BASE,3.14159+X,Y,LIMIT,R(LT+2)) 
 
CALL PNTOUT(A,N,'ABCD') 
 
CALL EXIT 
 
CALL MULT(A,B,*10,*20,C)       ! The asterisks and ampersands denote 
CALL SUBA(X,&30,&50,Y)         !     alternate returns 

The following example shows a subroutine with argument keywords:


PROGRAM KEYWORD_EXAMPLE 
  INTERFACE 
    SUBROUTINE TEST_C(I, L, J, KYWD2, D, F, KYWD1) 
      INTEGER I, L(20), J, KYWD1 
      REAL, OPTIONAL :: D, F 
      COMPLEX KYWD2 
      ... 
    END SUBROUTINE TEST_C 
  END INTERFACE 
  INTEGER I, J, K 
  INTEGER L(20) 
  COMPLEX Z1 
  CALL TEST_C(I, L, J, KYWD1 = K, KYWD2 = Z1) 
  ... 

The first three actual arguments are associated with their corresponding dummy arguments by position. The argument keywords are associated by keyword name, so they can appear in any order.

Note that the interface to subroutine TEST has two optional arguments that have been omitted in the CALL statement.

The following is another example of a subroutine call with argument keywords:


CALL TEST(X, Y, N, EQUALITIES = Q, XSTART = X0) 

The first three arguments are associated by position.

For More Information:

7.4 CASE Construct

The CASE construct conditionally executes one block of constructs or statements depending on the value of a scalar expression in a SELECT CASE statement.

The CASE construct takes the following form:

  • [name:] SELECT CASE (expr)
  • [CASE (case-value [,case-value]...) [name]
  • block]...
  • [CASE DEFAULT [name]
  • block]
  • END SELECT [name]

name

Is the name of the CASE construct.

expr

Is a scalar expression of type integer, logical, or character (enclosed in parentheses). Evaluation of this expression results in a value called the case index.

case-value

Is one or more scalar integer, logical, or character initialization expressions enclosed in parentheses. Each case-value must be of the same type and kind parameter as expr. If the type is character, case-value and expr can be of different lengths, but their kind parameter must be the same.

Integer and character expressions can be expressed as a range of case values, taking one of the following forms:

  • low:high
  • low:
  • :high

Case values must not overlap.

block

Is a sequence of zero or more statements or constructs.

Rules and Behavior

If a construct name is specified in a SELECT CASE statement, the same name must appear in the corresponding END SELECT statement. The same construct name can optionally appear in any CASE statement in the construct. The same construct name must not be used for different named constructs in the same scoping unit.

The case expression (expr) is evaluated first. The resulting case index is compared to the case values to find a matching value (there can only be one). When a match occurs, the block following the matching case value is executed and the construct terminates.

The following rules determine whether a match occurs:

The following are all valid case values:


CASE (1, 4, 7, 11:14, 22)      ! Individual values as specified: 
                               !     1, 4, 7, 11, 12, 13, 14, 22 
CASE (:-1)                     ! All values less than zero 
CASE (0)                       ! Only zero 
CASE (1:)                      ! All values above zero 

If no match occurs but a CASE DEFAULT statement is present, the block following that statement is executed and the construct terminates.

If no match occurs and no CASE DEFAULT statement is present, no block is executed, the construct terminates, and control passes to the next executable statement or construct following the END SELECT statement.

Figure 7-1 shows the flow of control in a CASE construct.

Figure 7-1 Flow of Control in CASE Constructs


You cannot use branching statements to transfer control to a CASE statement. However, branching to a SELECT CASE statement is allowed. Branching to the END SELECT statement is allowed only from within the CASE construct.

Examples

The following are examples of CASE constructs:


INTEGER FUNCTION STATUS_CODE (I) 
  INTEGER I 
  CHECK_STATUS: SELECT CASE (I) 
  CASE (:-1) 
    STATUS_CODE = -1 
  CASE (0) 
    STATUS_CODE = 0 
  CASE (1:) 
    STATUS_CODE = 1 
  END SELECT CHECK_STATUS 
END FUNCTION STATUS_CODE 
 
SELECT CASE (J) 
CASE (1, 3:7, 9)    ! Values: 1, 3, 4, 5, 6, 7, 9 
  CALL SUB_A 
CASE DEFAULT 
  CALL SUB_B 
END SELECT 

The following three examples are equivalent:


1. SELECT CASE (ITEST .EQ. 1) 
   CASE (.TRUE.) 
     CALL SUB1 () 
   CASE (.FALSE.) 
     CALL SUB2 () 
   END SELECT 
 
2. SELECT CASE (ITEST) 
   CASE DEFAULT 
     CALL SUB2 () 
   CASE (1) 
     CALL SUB1 () 
   END SELECT 
 
3. IF (ITEST .EQ. 1) THEN 
     CALL SUB1 () 
   ELSE 
     CALL SUB2 () 
   END IF 


Previous Next Contents Index