Node: Block Data and Libraries, Next: Loops, Previous: Advantages Over f2c, Up: Collected Fortran Wisdom
To ensure that block data program units are linked, especially a concern
when they are put into libraries, give each one a name (as in
BLOCK DATA FOO
) and make sure there is an EXTERNAL FOO
statement in every program unit that uses any common block
initialized by the corresponding BLOCK DATA
.
g77
currently compiles a BLOCK DATA
as if it were a
SUBROUTINE
,
that is, it generates an actual procedure having the appropriate name.
The procedure does nothing but return immediately if it happens to be
called.
For EXTERNAL FOO
, where FOO
is not otherwise referenced in the
same program unit, g77
assumes there exists a BLOCK DATA FOO
in the program and ensures that by generating a
reference to it so the linker will make sure it is present.
(Specifically, g77
outputs in the data section a static pointer to the
external name FOO
.)
The implementation g77
currently uses to make this work is
one of the few things not compatible with f2c
as currently
shipped.
f2c
currently does nothing with EXTERNAL FOO
except
issue a warning that FOO
is not otherwise referenced,
and, for BLOCK DATA FOO
,
f2c
doesn't generate a dummy procedure with the name FOO
.
The upshot is that you shouldn't mix f2c
and g77
in
this particular case.
If you use f2c
to compile BLOCK DATA FOO
,
then any g77
-compiled program unit that says EXTERNAL FOO
will result in an unresolved reference when linked.
If you do the
opposite, then FOO
might not be linked in under various
circumstances (such as when FOO
is in a library, or you're
using a "clever" linker--so clever, it produces a broken program
with little or no warning by omitting initializations of global data
because they are contained in unreferenced procedures).
The changes you make to your code to make g77
handle this situation,
however, appear to be a widely portable way to handle it.
That is, many systems permit it (as they should, since the
FORTRAN 77 standard permits EXTERNAL FOO
when FOO
is a block data program unit), and of the ones
that might not link BLOCK DATA FOO
under some circumstances, most of
them appear to do so once EXTERNAL FOO
is present in the appropriate
program units.
Here is the recommended approach to modifying a program containing a program unit such as the following:
BLOCK DATA FOO COMMON /VARS/ X, Y, Z DATA X, Y, Z / 3., 4., 5. / END
If the above program unit might be placed in a library module, then
ensure that every program unit in every program that references that
particular COMMON
area uses the EXTERNAL
statement
to force the area to be initialized.
For example, change a program unit that starts with
INTEGER FUNCTION CURX() COMMON /VARS/ X, Y, Z CURX = X END
so that it uses the EXTERNAL
statement, as in:
INTEGER FUNCTION CURX() COMMON /VARS/ X, Y, Z EXTERNAL FOO CURX = X END
That way, CURX
is compiled by g77
(and many other
compilers) so that the linker knows it must include FOO
,
the BLOCK DATA
program unit that sets the initial values
for the variables in VAR
, in the executable program.