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