Terms are used in a precise way to describe a programming language, so this chapter introduces the fundamental terms needed to understand Fortran. You can consult the glossary in this manual for definitions of terms.
One of the major concepts involves the organization of a Fortran program. This topic is introduced in this chapter by presenting the high-level syntax rules for a Fortran program, which includes the principal constructs and statements that form a program. This chapter also describes the order in which constructs and statements must appear in a program and concludes with an example of a short Fortran program.
In examining the basic concepts in Fortran, it helps to trace some of the important steps in its evolution. The results of the first few steps are familiar to Fortran programmers, but the later ones become relevant only when the new features of Fortran are used.
The first version of Fortran produced in the late 1950s did not have user-defined subroutines or functions, but it did contain intrinsic functions.
Programmers soon realized the benefits of isolating definitive chunks of code into separate units known as function and subroutine subprograms. This not only provided a mechanism for structuring a program but permitted subprograms to be written once and then be called many times by the same program (or even be used by more than one program). Equally important, subprograms could be compiled separately.
With this powerful tool came complications. For example, if both the main program and a subprogram use the variable named X, what is the connection between them? The answer is that, in general, there is no connection between X in the main program and X in a subprogram. Subprograms are separately compilable; an X in a different subprogram is not even known at compile time, so the simplest thing to do is have no connection between variables with the same name in different program units. Thus, if two different programmers work on different program units, neither one needs to worry about names picked by the other. This idea is described by saying that the two Xs have different scope.
A subroutine could be written to do a summation of the first hundred integers and print the results. For example:
SUBROUTINE TOTAL M = 0 DO I = 1, 100 M = M + I END DO WRITE(6, 9) M 9 FORMAT(I10) RETURN END
With this subroutine available, the main program could be written as follows:
CALL TOTAL STOP END
Suppose you decide that the subroutine would be more generally useful if it computed the sum but did not print it, as follows:
SUBROUTINE TOTAL M = 0 DO I = 1, 100 M = M + I END DO RETURN END
A first attempt to use this subroutine might produce the following erroneous program:
CALL TOTAL WRITE(6, 9) M 9 FORMAT(I10) STOP END
This does not work because the variable M in the subroutine has nothing to do with variable M in the main program. A connection between the two values should exist, so when subroutines and functions were introduced, two schemes were provided to communicate values between them and other program units: procedure arguments and common blocks.
The following two complete programs communicate values in two ways. The first, program ARGSUM, uses a subroutine argument, and the second, program COMSUM, uses a common block to communicate values. The names in the different program units identify completely separate variables, yet their values are communicated from one to the other by using either arguments or common blocks, so the name of the variable holding the sum in the subroutine need not be the same as the corresponding variable in the calling program.
PROGRAM ARGSUM CALL TOTAL(M) WRITE(6, 9) M 9 FORMAT(I10) END SUBROUTINE TOTAL(ITOTAL) ITOTAL = 0 DO I = 1, 100 ITOTAL = ITOTAL + I END DO END
Program COMSUM, which follows, performs the same computation as program ARGSUM:
PROGRAM COMSUM COMMON /CB/ M CALL TOTAL WRITE(6, 9) M 9 FORMAT(I10) END SUBROUTINE TOTAL COMMON /CB/ ITOTAL ITOTAL = 0 DO I = 1, 100 ITOTAL = ITOTAL + I END DO END
To describe even these simple cases and appreciate how they work already requires the introduction of some terms and concepts. To precisely describe the phenomenon that the subroutine variable ITOTAL is not known outside the subroutine, the concept of scope is used. Because the scope of a variable in a common block is local, the scope of ITOTAL includes only the subroutine — not the main program.
The scope of ITOTAL is the subroutine; the scope of the variable M is the main program. However, the scope of the common block name CB is global. The term association is used to describe the connection between M in the main program and ITOTAL in the subroutine. In the first example it is argument association, and in the second it is storage association.
To summarize, the scope of a variable is that part of the program in which it is known and can be used. Two variables may have the same name and nonoverlapping scopes; for example, there may be two completely different variables named X in two different subprograms. Association of variables means that there may be two different names for the same object; this permits sharing values under certain conditions.
With arguments available, it is natural to generalize the computation somewhat to allow the upper limit of the sum (100 in the example) to vary. Also, a function is more natural in this case than a subroutine, because the object of the computation is to return a single value. These changes produce the following program:
PROGRAM PTOTAL INTEGER TOTAL PRINT *, TOTAL(100) END FUNCTION TOTAL(N) INTEGER TOTAL TOTAL = 0 DO I = 1, N TOTAL = TOTAL + I END DO END
In this example, the scope of N is function TOTAL, but when function TOTAL is called from the main program in the PRINT statement, the value of N, through argument association, becomes 100. The scope of variable I is function TOTAL. The scope of function TOTAL is the whole program, but its type must be declared in the main program because by the implicit typing rules, TOTAL is not of type integer. Also note that there is a function named TOTAL, with global scope, and a variable named TOTAL is local to the function. The use of identifier TOTAL determines whether it is the local variable TOTAL or the global function name TOTAL. When TOTAL is used with an argument list, it is the function name; when used inside the function subprogram defining the function TOTAL, it is the local variable. Variable TOTAL computes and stores the value that is returned as the value of the function TOTAL.
It is possible to rewrite the example using internal procedures:
PROGRAM DO_TOTAL PRINT *, TOTAL(100) CONTAINS FUNCTION TOTAL(N) INTEGER TOTAL TOTAL = 0 DO I = 1, N TOTAL = TOTAL + I END DO END FUNCTION TOTAL END PROGRAM DO_TOTAL
This is similar to the previous example, but the function is placed prior to the END statement of the main program and the CONTAINS statement is inserted to mark the beginning of any internal functions or subroutines. In this case, the function TOTAL is not global but is local to the program DO_TOTAL. Also, the FUNCTION statement for TOTAL and the specifications that follow it specify TOTAL as a function of type integer with one integer argument N. The type of TOTAL must not be declared in the specification part of the program DO_TOTAL; to do so would create a duplicate declaration of TOTAL. The information about the type of the function and type of the argument is called the interface to the internal function.
To illustrate some other rules about scoping and association related to internal procedures, the example can be changed back to one that uses a subroutine, but one that is now internal.
PROGRAM DO_TOTAL INTEGER TOTAL CALL ADD_EM_UP(100) PRINT *, TOTAL CONTAINS SUBROUTINE ADD_EM_UP(N) TOTAL = 0 DO I = 1, N TOTAL = TOTAL + I END DO END SUBROUTINE ADD_EM_UP END PROGRAM DO_TOTAL
The preceding example shows that TOTAL in the internal subroutine and TOTAL in the main program are, indeed, the same variable. It does not need to be declared type integer in the subroutine. This is the result of host association, wherein internal procedures inherit information about variables from their host, which is the main program in this case. Variable I does not appear in the main program, so its scope is the internal subroutine.
MODULE TOTAL_STUFF CONTAINS FUNCTION TOTAL(N) INTEGER TOTAL, N, I TOTAL = 0 DO I = 1, N TOTAL = TOTAL + I END DO END FUNCTION TOTAL END MODULE TOTAL_STUFF PROGRAM DO_TOTAL USE TOTAL_STUFF PRINT *, TOTAL(100) END PROGRAM DO_TOTAL
The module and the program could be in different files. They can be compiled like subroutines, but unlike subroutines, the module must be available to the compiler when program DO_TOTAL is compiled.
The scope of variables N and I is function TOTAL; N gets its value 100 by argument association. The module name TOTAL_STUFF is global and any program can use the module, which causes the type and definition of function TOTAL to become available within that program. This is called use association.
When more extensive examples are constructed using such features as internal procedures within a procedure in a module, there is a need to have a deeper understanding of scope and association. These topics are introduced briefly in the following section and discussed in more detail in the Fortran Language Reference Manual, Volume 2.
The scope of a program entity is that part of the entire executable program in which that entity is known, is available, and can be used. Some of the parts of a program that constitute the scope of entities are called scoping units. Scoping units range in extent of inclusiveness from parts of a statement to an entire program unit.
Some entities have scopes that are something other than a scoping unit. For example, the scope of a name, such as a variable name, can be global to an executing program. For more information on name scope and scoping units, see the Fortran Language Reference Manual, Volume 2.
The term association describes how different entities in the same program unit or different program units can share values and other properties. It is also a mechanism by which the scope of an entity is made larger. For example, argument association allows values to be shared between a procedure and the program that calls it. Storage association, set up by the use of EQUIVALENCE and COMMON statements, for example, allows two or more variables to share storage, therefore values, under certain circumstances. Use association and host association both allow entities described in one part of a program to be used in another part of the program. Use association makes entities defined in modules accessible, and host association makes entities in the containing environment available to an internal or module procedure. The complete description of all categories of association are described in the Fortran Language Reference Manual, Volume 2.