[comp.os.vms] Losing values stored in FORTRAN COMMON blocks

smith%eri.DECnet@MGHCCC.HARVARD.EDU ("ERI::SMITH") (09/17/87)

>The following F77 program excerpt used to work fine on a PDP11/44 running
>RSX11M+, but does not on our uVax running uVMS 4.4.   Any thoughts ?
>* Main Program 
	CALL A
	CALL B

>...For some unknown reason, between storing the common area values in
>subroutine A, and recalling them in subroutine B, the values changed.

A perfect example of why it is important to have access to accurate
information on the FORTRAN standard, and not merely the manufacturers'
documentation or experience with a particular implementation.

Both FORTRAN 66 and FORTRAN 77 place restrictions on the use of COMMON
blocks.  The restrictions are easily understood if you think about
implementations as overlays.  The main purpose of COMMON blocks is to
permit communication between subprograms, not preservation of values
between calls.

Section 15.8.4 of ANSI X3.9-1978 puts it this way:

"Execution of a RETURN statement causes all entities within the
subprogram to become undefined, except for the following: (1) entities
specified by SAVE statements; (2) entities in blank common [i.e. yes,
indeed, blank common is explicitly different from named common--DPBS];
(3) initially defined entities that have neither been redefined or
become undefined; (4) entities in a named common block that appears in
the subprogram AND APPEARS IN AT LEAST ONE OTHER PROGRAM UNIT THAT IS
REFERENCING, EITHER DIRECTLY OR INDIRECTLY, THE SUBPROGRAM [emphasis 
mine]."

In other words, even though the common blocks in subroutines A and B are
labelled with the same name, ACCORDING TO THE STANDARD the contents of
the common block becomes undefined when you exit from A because the calling
subprogram does not reference the common block.

This is a common source of errors, because as a result of either a) the
implementation, or b) the breaks of the game, the contents of common blocks
may be preserved even when the FORTRAN standard doesn't guarantee it.

Now, I'm going to go out on a limb and put my reputation on the line by
making a statement on the basis of the standard without actually testing
it.  One fix would be to use blank COMMON instead of named COMMON.  Another
fix is to duplicate the named COMMON declaration in the subroutine that
calls both A and B.  In general, if you want COMMON to behave the way the
querent expects, the safe, easy thing to do is to put duplicates of all
COMMON declarations into the main program.

Now I'm going to go a little further out on a limb.  The SAVE statement
is a FORTRAN IV innovation that I've never used personally.  However, it
appears that one of the things you can do with it is to tell FORTRAN the
names of named common blocks that you think should not evaporate on
subroutine exit.

P.S. I just looked in the manual "Programming in VAX FORTRAN".  I didn't
go through it with a fine-toothed comb, but in at least one place it
seems to me to be misleading on this point.  Section 8.2, COMMON
statement, which is where I'd expect to find it, says "When you 
declare common blocks of the same name in different program units,
these blocks all share the same storage area when the program units
are combined into an executable program."  Well, I guess that could
be true--it doesn't say that they have EXCLUSIVE use of that area.
--------------------------------------------------------------------
Daniel P. B. Smith         ARPA: smith%eri.decnet@mghccc.harvard.edu
Eye Research Institute     CompuServe: 74706,661
20 Staniford Street        Telephone (voice): 617 742-3140
Boston, MA 02114
--------------------------------------------------------------------
"We are in great haste to construct a magnetic telegraph from Maine to
Texas; but Maine and Texas, it may be, have nothing important to
communicate."--Thoreau
------