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 a FORTRAN-specific mechanism for indirectly 
 passing variables to procedures, i.e. not by procedure arguments. 
 This mechanism is a refinement of the global variables used in 
 other programming languages.

 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.

 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.

  +-----------------------------------------+
  |  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