Intel® Fortran Compiler Classic and Intel® Fortran Compiler Developer Guide and Reference

ID 767251
Date 3/31/2023
Public

A newer version of this document is available. Customers should click here to go to the newest version.

Document Table of Contents

Global Data

A module variable or a common block can interoperate with a C global variable if the Fortran entity uses the BIND attribute and the members of that entity are also interoperable. Consider the entities c_extern, c2, com and single in the following module's interoperability example:

module LINK_TO_C_VARS
   use, intrinsic :: ISO_C_BINDING
   integer(C_INT), BIND(C) :: c_extern
   integer(C_LONG) :: c2
   BIND(C, name=’myVariable’) :: c2
   common /com/ r,s
   real(C_FLOAT) :: r,s,t
   BIND(C) :: /com/, /single/
   common /single/ t
end module LINK_TO_C_VARS

This example can interoperate with the following C external variables:

int c_extern;
long myVariable;
struct {float r, s;} com;
float single;

Accessing global parameters example:

    MODULE Examp
      integer, BIND(C)::idata(20)
      real::rdata(10)
    END MODULE

In Fortran, a variable can access a global parameter by using the standard BIND C attribute.

In the above, two external variables are created (the latter with proper case and decoration): idata and foo_mp_rdata.

Use the BIND attribute to resolve name discrepancies with C, seen in the global variable statement example:

  int idata[20]; // declared as global (outside of any function)

Fortran can declare the variable global (COMMON) and other languages can reference it as external, for example:

 ! Fortran declaring PI global
  real pi_r
  COMMON /pi/ pi_r ! Common Block and variable names
  BIND(C)::/pi/

Use of BIND(C) above means that the name will be appropriately decorated for the target and made lowercase. In C, the variable is referenced as an external with the statement:

  //C code with external reference to pi
  extern float pi;

The global name C references is the name of the Fortran common block (pi), not the name of a variable within a common block (pi_r). Therefore, you cannot use blank common (unnamed) to make data accessible between C and Fortran.

COMMON

To reference C structures from Fortran common blocks and vice versa, you must take into account how common blocks and structures differ in their methods of storing member variables in memory. Fortran places common block variables into memory in order as close together as possible, with the following rules:

  • A single BYTE, INTEGER(1), LOGICAL(1), or CHARACTER variable in common block list begins immediately following the previous variable or array in memory.

  • All other types of single variables begin at the next even address immediately following the previous variable or array in memory.

  • All arrays of variables begin on the next even address immediately following the previous variable or array in memory, except for CHARACTER arrays which always follow immediately after the previous variable or array.

  • All common blocks begin on a four-byte aligned address.

Because of these rules, you must consider the alignment of C structure elements with Fortran common block elements. Specifically, you should ensure interoperability either by making all variables exactly equivalent types and kinds in both languages (using only 4-byte and 8-byte data types in both languages simplifies this) or by using the C pack pragmas in the C code around the C structure. This makes C data packing compatible with Fortran data packing.

As an example, suppose your Fortran code has a common block named Really, as shown in the Fortran example::

  USE, INTRINSIC::ISO_C_BINDING
    REAL (C_float)::x,y,z(6)
    REAL (C_double)::ydbl
    COMMON, BIND(C) / Really /x, y, z(6), ydbl

You can access this data structure from your C code with the following external data structures, as shown in the C example:

 #pragma pack(2)
 extern struct {
  float x, y, z[6];
  double ydbl;
 } Really;
 #pragma pack()

To restore the original packing, you must add #pragma pack() at the end of the C structure.

You can also access C structures from Fortran by creating common blocks that correspond to those structures. This is the reverse case from that shown above. However, the implementation is the same; after common blocks and structures have been defined and given a common address (name), and, assuming the alignment in memory has been accounted for, both languages share the same memory locations for the variables.

Once you have accounted for alignment and padding, you can give C access to an entire common block or set of common blocks. Alternatively, you can pass individual members of a Fortran common block in an argument list, just as you can any other data item.

See Also