2-7 COMMON BLOCKS
******************
(Thanks to Keith Bierman for the excellent comments, and to
Craig Burley for making clear some subtle points)
Common blocks are considered by some a "dusty" feature of FORTRAN 77,
which is an inevitable source of problems, and should be replaced
by the modules of Fortran 90. The "rational subsets" of Fortran 90,
ELF90 by Lahey, and F by Imagine1, do not support common blocks.
The variables in a common block are re-identified in each procedure
using storage association, a mechanism that is considered inferior
to naming each one.
Another view: Actually, it often isn't, but they should be coherent,
distinct organizations of truly global data, rather than convenient
placeholders for things you don't want to bother passing among a
few procedures.
The uses of common blocks
-------------------------
Common blocks are a FORTRAN-specific mechanism for indirectly passing
variables to procedures, i.e. not by procedure arguments. The common
block mechanism is a refinement of the global variables used in other
programming languages, as you can control which procedures have access
to a common block and which will not (by including or not the common
statement in these procedures).
When you have variables that are passed along a chain of procedure calls
but are used only in some of them, you can avoid repeatedly entering
them into argument and declaration lists by putting them in a common
block and declaring it only in the procedures that actually use them.
Eliminating these argument passing operations may save CPU time as well.
Using common blocks can shorten argument and declaration lists,
but the indirect links created between different parts of the program
are confusing and hard to trace, and a constant source of nasty bugs.
Note that common blocks doesn't have the full functionality of passing
variables by procedure calls, the FORTRAN 77 standard forbids common
block variables from using the adjustable array mechanism (only the
dimensional info may be passed in the block, but not the variable),
so their dimensions must be specified explicitly with constants.
This is a serious limitation, you can't write nice general-purpose
routines that can be put in an object library. A partial solution
is including a file that contains the required dimensional information
in each procedure that use the common block.
+-----------------------------------------+
| AVOID USING COMMON BLOCKS IF POSSIBLE |
+-----------------------------------------+
Losing variable values
----------------------
COMMON variables may LOSE THEIR VALUES after a subprogram return,
you can use the SAVE statement on each re-declaration, or declare
the COMMON block in the main program to avoid such situations.
Losing COMMON (and other) variable values was inevitable with the
oldtime overlay loaders used before the age of virtual memory,
when a COMMON block wasn't used by one of the currently executing
procedures the memory area allocated to it was reallocated for
other purpose. Virtual memory made this technique unnecessary
but as the standard allows this behaviour you should still guard
against it.
A static code checker like FTNCHEK (used with the -volatile option)
can locate COMMON blocks that may have this problem.
Guidelines on COMMON usage
--------------------------
If you decide to use COMMON blocks, the following remarks
may help:
1) Character variables shouldn't be in the same COMMON
block with non-character variables. If you pass both
kinds, create one COMMON block for the character
variables, and one for the numeric variables.
The standard imposes this requirement to ensure that
operations associating variables of different types
will give portable results, without having to specify
storage sizes. See the chapter on memory allocation
for a discussion of this subject.
Mixing character and numeric variables in a common
block may create a problem when you port your program.
Also there might have been an ancient system or two
that allowed easier implementation of FORTRAN without
such mixing, but on most modern systems, it's no problem.
2) Declare array dimensions explicitly in a type declaration,
or in a COMMON block declaration, don't specify the
dimensions with the DIMENSION statement.
3) The best policy is to make all re-declarations of a COMMON
block exact copies, with the same variable names, in the
same order, and with the same data types and sizes.
On all re-declarations of a COMMON block, also make the type
declaration lists of the COMMON block members exact copies.
A possible way to ensure consistent declarations is to use
the non-standard INCLUDE statement or a preprocessor,
(e.g. the #include directive of cpp - the C pre-processor
found in most unix f77 implementations).
4) A good rule is to order the variables of COMMON blocks
in a size decreasing order:
COMPLEX*32, COMPLEX*16, REAL*16
COMPLEX*8, REAL*8, INTEGER*8
REAL*4, INTEGER*4, LOGICAL
INTEGER*2
BYTE, CHARACTER
Ordered that way the 'smaller' variables will not get
the 'larger' ones out of alignment.
Usually INTEGER is INTEGER*4, REAL is REAL*4 and DOUBLE
PRECISION is REAL*8, but some machines have unusual sizes
(e.g. on CRAYs INTEGER is 64 bits but only 46 are used by
default, REAL is REAL*8, DOUBLE PRECISION is REAL*16 but
two bytes are not used), on other machines a character
storage unit may be 2 bytes or even variable-length
instead of the usual 1.
5) All COMMON blocks can only legally be initialized with
a block data subprogram.
6) A blank COMMON block may behave differently from named
COMMON blocks:
a) Blank COMMON variables never become undefined
as a result of procedures return
b) A blank COMMON block may be re-declared with
different size, avoid using that feature.
c) A blank COMMON block may not be initialized by
a DATA statement
Return to contents page