next up previous contents
Next: BLOCK DATA statements Up: The Building Blocks of Previous: Taylor Approximation of the   Contents

F77 Global Storage. Storage Association.

The default global storage facility in F77 are the COMMON blocks. It is likely that we will encounter them in older software; however, we encourage the use of modules, not COMMON blocks, whenever global storage is required.

The above version of our example program can be reformulated with COMMON blocks as follows:

 
program approx
  integer :: n
  real, dimension(0:10) :: b
  common /coeff/ n, b
  print*, "please input order (n <= 10)"
  read*,  n
  n = min(n, 10)
  call taylor_exp
!
  do i=-3,3
    x= 2.0**i
    print*, x,") exp=",exp(x), &
             ";  taylor=", eval(x)
  end do
end program approx

subroutine taylor_exp
!  calculate the first
!  n coefficients in
!  the taylor approx. of exp
  integer :: n
  real, dimension(0:10) :: b
  common /coeff/ n, b
!
  integer :: i
  b(0) = 1.0
  do i=1,n
    b(i) = b(i-1)/real(i)
  end do
end subroutine taylor_exp

real function eval(x)
! evaluate the order n
! polyn. with coefficients b(i)
  integer :: n
  real, dimension(0:10) :: b
  common /coeff/ n, b
!
  real, intent(in) :: x
  integer :: i
  eval = b(n)
  do i = n-1,0,-1
    eval = b(i)+x*eval
  end do  
end function eval

A common block declaration consists by the keyword COMMON, followed by the common block's name (included between slashes); common blocks are recognized by their names within all program units, i.e. COMMON block names are, by default, global names (they have to differ from any program unit name). In the declaration, the name is followed by the list of variables stored in the COMMON block.


All program units that invoke the
 
common /coeff/ ...
statement, for example, will have access to the common block /coeff/'s variables. Since we can have variables shared by multiple units, common blocks are a mean of implementing global storage. Note that an argument of a function or subroutine cannot be simultaneously a common block variable in the same procedure.

Physically, a common block is a contiguous zone of memory (a ``block'' of memory) in which succesive chunks of bytes are allocated to succesive variables (i.e. to the variables specified in the definition of the COMMON block). Specifically, INTEGERs, REALs and LOGICALs are allocated 1 storage unit in the block, DOUBLE PRECISION and COMPLEX variables are given 2 storage units (1 unit is usually 4 bytes, but depends on the implementation). Characters are considered to have a different storage unit, incompatible with the numerical storage unit; they are therefore incompatible with the numerical types; chracter and numerical variables cannot be part of the same COMMON block.

The memory block can be seen by any program unit which includes its declaration, being therefore COMMON to several program units.

25<25 25<25 SetFigFont>pt@pt xxxxxxsplain


This storage scheme is also the main weakness of COMMON blocks. The reason is that the names of variables are local to the program unit which declares them, while the COMMON block name is global. Thus, different program units can access the same common block, but can refer to the common block variables with different (local) names. Of course, what counts is the relative position of a variable within the block - the name is just a (local) alias for this position. Therefore, the types and the order of common block variables have to be the same, but their names can differ (pretty much like the list of formal (dummy) vs. the list of actual arguments).

For example, consider the following subroutine which prints the first two elements of the COMMON block COEFF.

 
subroutine p2
  integer :: n, p
  common /coeff/ n, p 
  print*, n, p 
end subroutine  p2

The compiler cannot check that types of the succesive variables in COMMON blocks match for different common block definitions; it will just check that local definitions are consistent. Now, our intent was to have first an integer (n), then a real number b(0); by mistake, we declared both integers, and the compiler cannot help us; in consequence, the 32 bits of the real number b(0) will be interpreted as the 32 bits of a signed integer (in two's complement) p; instead of 1.0 we obtain 1065353216.

In addition, common blocks containing data of heterogeneous(different) types may lead to memory missalignments.


next up previous contents
Next: BLOCK DATA statements Up: The Building Blocks of Previous: Taylor Approximation of the   Contents
Adrian Sandu 2001-08-26