Fortran programmers have traditionally relied on the common
block to share large amounts of data among different program units.
The convenience offered by the common block is that it can give
storage access to program units that don't otherwise communicate
with each other, even when they reside in separate files.[4]
Although C has no common blocks, it does provide external
variables, which can also be used to share data among
different parts of a C program. A variable becomes external when
defined outside any function. To become accessible to a function,
the external variable must be declared without being defined within
the function that wants to access it. (In C, a variable is defined
when storage is allocated for it, and declared
when its name and type are stated without any storage allocation.)
To declare a variable in C without defining it, you use the extern
storage class specifier, which tells the linker to look elsewhere
for the definition.
For example, the following statement (assuming that it is
made outside any function) declares and defines the external variable
some_data:
The next statement declares some_data
without defining it, making it available to the function in which
the declaration is made:
Fortran's common block and C's extern
statement can work together to enable Fortran program units to share
data with an HP C function. The storage is actually allocated
(or in C terminology, defined) in the
Fortran source file. The C source file declares but does not define
the name of the common block, using the extern
specifier. The linker resolves the reference at linktime.
Consider the following Fortran statements, which declare an
array of integers and place the array in a common block named globals:
INTEGER, DIMENSION(100) :: global_array COMMON /globals/global_array |
The next statement is the extern
statement that references (in C terminology, declares)
the common block, making it available to a function in the C object
file:
Note that the extern specifier
references the name of the common block, globals,
not the name of the array. From C's point of view, the
common block is treated as though it were the array.
The common block to be shared with a C function can contain
more than one data item. To do so, the C source file must declare
a structure whose members match the data items in common. Any C
function needing access to an item in common uses the extern
statement to declare a variable of the structure type. The name
of the variable is that of the common block. To access an individual
data item, the function uses the C notation for referencing members
of a structure.
HP Fortran 90 uses the same packing and
alignment rules when laying out common blocks in memory that HP C
uses for structures. However, the programmer must be sure to declare
the number, types, and sizes of the structure members in the same
order as they appear in the common block. Refer to Table 8-1 “Data type correspondence for HP Fortran 90
and C ” for the data
type correspondences for both languages.
The following example program consists of two source files
that contain the Fortran main program unit and a C function called
from Fortran. The main program unit specifies a common block having
two double-precision variables. It writes to one of the variables
and calls the C function. The C function reads the variable written
by Fortran and writes to the other one. After the call returns,
Fortran reads both variables.
The following are examples of Fortran and C source files.
Example 8-10 shared_common.f90
PROGRAM main ! This program uses the common block to share data with ! the C function get_nlog. C uses a structure type to ! declare the same items in common. REAL(KIND=8) :: num, nlog_of_num COMMON /globals/num, nlog_of_num ! a header for the table that is printed by the following ! DO loop PRINT *, "Number Natural Log of Number" PRINT *, "-------+-----------------------" ! At each iteration, write a value to the common block ! variable num, call the C function get_nlog, and ! print the contents of both common block variables ! to the screen. DO num = 2.0, 10.0 CALL get_nlog() PRINT 10, num, '|', nlog_of_num END DO 10 FORMAT(3X, F3.0, 2X, A, 8X, F5.2) END PROGRAM main |
Example 8-11 shared_struct.c
#include <stdio.h> #include <math.h> /* declare a structure whose members match the data items * in the Fortran common block */ struct glob { double num; double nlog_of_num; } globals; /* get_nlog: reads the value in globals.num, passes it * to log() in the math library, and writes the write the * return value to globals.nlog_of_num */ void get_nlog(void) { /* declare the name of the common block defined in the * Fortran file */ extern struct glob globals; globals.nlog_of_num = log(globals.num); } |
Here are the command lines to compile, link, and execute the
program, followed by the output from a sample run. The -lm
option at the end of second command line tells the linker to look
in the math library for the log
function:
$ cc -Aa -c shared_struct.c $ f90
shared_common.f90 shared_struct.o -lm $ a.out Number Natural Log of Number -------+----------------------- 2. | 0.69 3. | 1.10 4. | 1.39 5. | 1.61 6. | 1.79 7. | 1.95 8. | 2.08 9. | 2.20 10. | 2.30
|
See the HP Fortran 90 Programmer's Reference
for a full description of the COMMON
statement.