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