next up previous contents
Next: Obsolete and Deprecated Features Up: Professional Programmer's Guide to Previous: DATA Statement

Common Blocks

A common block is a list of variables and arrays stored in a named area which may be accessed directly in more than one program unit. Common blocks are mainly used to transfer information from one program unit to another; they can be used in as an alternative to argument-list transfers or in addition to them.

Common blocks are sometimes used to fit large programs into small computers by arranging for several program units to share a common pool of memory. This is not a recommended programming practice and is likely to become redundant with the spread of virtual-memory operating systems.

The name of a common block is an external name which must be different from all other global names, such as those of procedures, in the executable program. The variables and arrays stored with the block cannot be initialised in the normal way, but only in a BLOCK DATA program unit which was invented especially for this purpose.

Using Common Blocks

In most cases the best way to pass information from one program unit to another is to use the procedure argument list mechanism. This preserves the modularity and independence of procedures as much as possible. Argument lists are, however, less satisfactory in a group of procedures forming a package which have to share a large amount of information with each other. Procedure argument lists then tend to be come long, cumbersome, and even inefficient. If this package of procedures is intended for general use it is quite important to keep the external interface as uncomplicated as possible. This can be achieved by using the procedure argument lists only for import of information from and export to the rest of the program, and handling the communications between one procedure in the package and another with common blocks. The user is then free to ignore the internal workings of the package.

For example, in a simple package to handle a pen-plotter you may want to provide simple procedure calls such as:
tabular1781

These procedures clearly have to pass information from one to another about the current pen position, scaling factor, etc. A suitable common block definition might look like this:

 
       COMMON /PLOT/ OPENED, ORIGIN(2), PSCALE, NUMPEN 
       LOGICAL OPENED 
       INTEGER NUMPEN 
       REAL PSCALE, ORIGIN 
       SAVE /PLOT/

These specification statements would be needed in each procedure in the package.

Common Block Names

A program unit can access the contents of any common block by quoting its name in a COMMON statement. Common block names are always enclosed in a pair of slashes and can only be used in COMMON and SAVE statements. The common block itself has no data type and has a global name which must be distinct from the names of all program units. The name should also be distinct from all local names in each program units which access the block. Each program unit can make use of any number of different common blocks. There is also a special blank or un-named common block with unique properties which are covered in section 12.2 below.

The variables and arrays within a common block do not have any global status: they are associated with items in blocks bearing the same name in other program units only by their position within the block. Thus, if in one program unit specifies:

 
       COMMON /OBTUSE/ X(3)

and in another:

 
       COMMON /OBTUSE/ A, B, C

then, assuming the data types are the same, X(1) corresponds to A, X(2) to B, and X(3) to C. The COMMON statements here are effectively setting up different names or aliases for the same set of memory locations. The data types do not have to match provided the overall length is the same, but it is generally only possible to transfer information from one program unit to another if the corresponding items have the same data type. If they do not, when one item becomes defined all names for the same location which have a different data type become undefined. There is one minor exception to this rule: information may be transferred from a complex variable (or array element) to two variables of type real (or vice-versa) since these are directly associated with its real and imaginary parts.

Usually it is necessary to arrange for corresponding items to have identical data types; it also minimises confusion if the same symbolic names are used as well. The simplest way to achieve this is to use an INCLUDE statement, if your system provides one. The include-file should contain not only the COMMON statement but also all the associated type and SAVE statements which are necessary. It is, of course, still necessary to recompile every program unit which accesses the common block whenever its definition is altered significantly.

Declaring Arrays

The bounds of an array can be declared in the COMMON statement itself, or in a separate type or DIMENSION statement, but only in one of them. Thus:

 
       COMMON /DEMO/ ARRAY(5000) 
       DOUBLE PRECISION ARRAY

is exactly equivalent to:

 
       COMMON /DEMO/ ARRAY 
       DOUBLE PRECISION ARRAY(5000)
or even:
 
       COMMON /DEMO/ ARRAY 
       DOUBLE PRECISION ARRAY 
       DIMENSION ARRAY(5000)
but the verbosity of the third form has little to recommend it.

Data Types

The normal data type rules apply to variables and arrays in each common block. A type statement is not required if the initial letter rule would have the required effect, but type statements are advisable, especially if the implied-type rules are anywhere affected by IMPLICIT statements. Type statements may precede or follow the COMMON statement. Similarly the lengths of character items should be specified in a separate type statement: these cannot be specified in the COMMON statement.

Storage Units

The length of each common block is measured in storage units, as described in section 5.1. In summary, integer, real, and logical items occupy one numeric storage unit each; complex and double precision items occupy two each. To maximise portability, character storage units are considered incommensurate with numerical storage units. For this reason character and non-character items cannot be mixed in the same common block.

In practice this often means that two common blocks are needed to hold a particular data structure: one for the character items and one for all the others. If, in the first example, it had been necessary for the plotting package to store a plot title this would have to appear in a separate common block such as:

 
       COMMON /PLOTC/ TITLE 
       CHARACTER TITLE*40 
       SAVE /PLOTC/

It is good practice to use related names for the blocks to indicate that the character and non-character items are used in conjunction.

The length of a named common block must be the same in each program unit in which it appears. Obviously the easiest way to ensure this is to make the common block contents identical in each program unit. Note, however, that there is no requirement for data types to match, or for them to be listed in any particular order, provided the items are not used for information transfer, and provided the total length of the block is the same in each case. Thus these common blocks are both 2000 numerical storage units in length:

 
       COMMON /SAME/ G(1000) 
       DOUBLE PRECISION G 

       COMMON /SAME/ A, B, C, R(1997) 
       REAL A, R 
       LOGICAL B 
       INTEGER C

Items in a common block are stored in consecutive memory locations. Unfortunately there a few computer systems which require double precision and complex items to be stored in even-numbered storage locations: these may find it hard to cope with blocks which contain a mixture of data types. Machines with this defect can nearly always be placated by arranging for all double precision and complex items to come at the beginning of each block.

SAVE Statements and Common Blocks

Items in common blocks may become undefined when a procedure returns control to the calling unit just like local variables and arrays. This will not, however, occur in the case of the blank common block nor in any common block which is also declared in a program unit which is higher up the current chain of procedure calls. Since the main program unit is always at the top of the chain any common block declared in the main program can never become undefined in this way. In all other cases it is prudent to use SAVE statements.

The individual items in common blocks cannot be specified in a SAVE statement, only the common block name itself. Thus:

 
       SAVE /SAME/, /DEMO/

If a common block is saved in any program unit then it must be saved in all of them. The SAVE statement ought therefore to be included with the COMMON and associated type statements if INCLUDE statements are used. If the program is later modified so that the common block is also declared in the main program this will bring a SAVE statement into the main program unit, but although it then has no effect, it does no harm.

Restrictions

The dummy arguments of a procedure cannot be members of a common block nor, in a function, can the variable which has same name as the function. There are also some restrictions on the use of common block items as actual arguments of procedure calls because of the possibility of multiple definition. For example, if a procedure is defined like this:

 
       SUBROUTINE SILLY(ARG) 
       COMMON /BLOCK/ COM

And the same common block is also used in the calling unit, with a common block item as the actual argument, such as:

 
       PROGRAM DUMMY 
       COMMON /BLOCK/ VALUE 
*... 
       CALL SILLY(VALUE)

Then both ARG and COM within the subroutine SILLY are associated with the same item, VALUE, and it is therefore illegal to assign a new value to either of them.

Blank Common Blocks

Common blocks are sometimes also used to reduce the total amount of memory used by a program by arranging for several program units to share the same set of memory locations. This is a difficult and risky procedure which should not be attempted unless all else fails.

Most Fortran systems operate a storage allocation system which is completely static: each program unit has a separate allocation of memory for its local variables and arrays. If several procedures each need to use large arrays internally the total amount of memory occupied by the program may be rather large. If a set of procedures can be identified which are invoked in sequence, rather than one calling another, it may be feasible to reduce the total memory allocation by arranging for them to share a storage area. Each will use the same common block for their internal array space.

Named common blocks are required to have the same length in each program unit: if they are used it is necessary to work out which one needs the most storage and pad out all the others to same length. An alternative is to the use the special blank (or un-named) common block which has the useful property that it may have a different length in different program units.

In one program unit, for example, you could specify:

 
       COMMON // DUMMY(10000)

and in another

 
       COMPLEX SERIES(512,512), SLICE(512), EXPECT(1024) 
       COMMON // SERIES, SLICE, EXPECT

The blank common block has two other special properties. Firstly it cannot be initialised by a DATA statement even within a BLOCK DATA program unit (but this is not a serious limitation for a block used just for scratch storage). Secondly items within the blank common block never become undefined as a result of a procedure exit. For this reason the blank common block cannot be specified in a SAVE statement.

COMMON Statement

A program unit may contain any number of COMMON statements, each of which can define contents for any number of different common blocks. COMMON statements are specification statements and have a general form:

COMMON / name/ list-of-items , / name / list-of-items ...

Each name is defined as a common block name, which has global scope. The Fortran Standard allows it to use the same name as an intrinsic function, a local variable, or local array but not that of a named constant or an intrinsic function. Each list of items can contain names of variables and arrays. The array name may be followed by a dimension specification provided that each array is only dimensioned once in each program unit. The comma shown before the second and subsequent block-name is optional.

The name of the blank common block is normally specified as two consecutive slashes (ignoring any intervening blanks) but if it is the first block in the statement then the pair of slashes may be omitted.

The contents of a common block are a concatenation of the all the definitions for it in the program unit. Thus:

 
       COMMON /ONE/ A, B, C, /TWO/ ALPHA, BETA, GAMMA 
       COMMON /TWO/ DELTA

defines two blocks, /ONE/ contains three items while /TWO/ contains four of them.

In procedures, variables which are dummy arguments or which are the same as the function name cannot appear in common blocks.

BLOCK DATA Program Units

The block data program unit is a special form of program unit which is required only if it is necessary to specify initial values for variables and arrays in named common blocks. The program unit starts with a BLOCK DATA statement, ends with an END statement, and contains only specification and DATA statements. Comment lines are also permitted. The block data program unit is not executable and it is not a procedure.

The next example initialises the items in the common block for the plotting package used in section 12.1, so that the initial pen position is at the origin, the scaling factor starts at one, and so on. Thus a suitable program unit would be:

 
       BLOCK DATA SETPLT 
*SETPLT initialises the values used in the plotting package. 
       COMMON /PLOT/ OPENED, ORIGIN(2), PSCALE, NUMPEN 
       LOGICAL OPENED 
       INTEGER NUMPEN 
       REAL PSCALE, ORIGIN 
       SAVE /PLOT/ 
       DATA OPENED/.FALSE./, ORIGIN/2*0.0/, PSCALE/1.0/ 
       DATA NUMPEN/-1/ 
       END

A block data unit can specify initial values for any number of named common blocks (blank common cannot be initialised). Each common block must be complete but it is not necessary to specify initial values for all of the items within it. There can be more than one block data program unit, but a given common block cannot appear in more than one of them.

For compatibility with Fortran66 it is also possible to have one un-named block data program unit in a program.

Linking Block Data Program Units

If, when linking a program, one of the modules containing a procedure is accidentally omitted the linker is almost certain to produce an error message. But, unless additional precautions are taken, this will not occur if a block data subprogram unit is omitted. The program may even appear to work without it, but is likely to produce the wrong answer.

There is a simple way to guard against this possibility: the name of the block data unit should be specified in an EXTERNAL statement in at least some of the program units in which the common block is used. There is no harm in declaring it in all of them. This ensures that a link-time reference will be generated if any of these other program units are used. There is a slight snag to this technique if an INCLUDE statement is used to bring the common block definition into each program unit including the block data unit. In order to avoid a self-reference, the include-file should not contain the EXTERNAL statement.

Despite this slight complication, this is a simple and valuable precaution. It also makes is possible to hold block data units on object libraries and retrieve them automatically when they are required, just like all other types of subprogram unit.


next up previous contents
Next: Obsolete and Deprecated Features Up: Professional Programmer's Guide to Previous: DATA Statement

Clive Page
Tue Feb 27 11:14:41 GMT 2001