[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7. Mixed-Language Programming

This chapter is about mixed-language interoperability, but also applies if one links Fortran code compiled by different compilers. In most cases, use of the C Binding features of the Fortran 2003 standard is sufficient, and their use is highly recommended.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.1 Interoperability with C

Since Fortran 2003 (ISO/IEC 1539-1:2004(E)) there is a standardized way to generate procedure and derived-type declarations and global variables which are interoperable with C (ISO/IEC 9899:1999). The bind(C) attribute has been added to inform the compiler that a symbol shall be interoperable with C; also, some constraints are added. Note, however, that not all C features have a Fortran equivalent or vice versa. For instance, neither C's unsigned integers nor C's functions with variable number of arguments have an equivalent in Fortran.

Note that array dimensions are reversely ordered in C and that arrays in C always start with index 0 while in Fortran they start by default with 1. Thus, an array declaration A(n,m) in Fortran matches A[m][n] in C and accessing the element A(i,j) matches A[j-1][i-1]. The element following A(i,j) (C: A[j-1][i-1]; assuming i < n) in memory is A(i+1,j) (C: A[j-1][i]).


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.1.1 Intrinsic Types

In order to ensure that exactly the same variable type and kind is used in C and Fortran, the named constants shall be used which are defined in the ISO_C_BINDING intrinsic module. That module contains named constants for kind parameters and character named constants for the escape sequences in C. For a list of the constants, see ISO_C_BINDING.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.1.2 Derived Types and struct

For compatibility of derived types with struct, one needs to use the BIND(C) attribute in the type declaration. For instance, the following type declaration

 
 USE ISO_C_BINDING
 TYPE, BIND(C) :: myType
   INTEGER(C_INT) :: i1, i2
   INTEGER(C_SIGNED_CHAR) :: i3
   REAL(C_DOUBLE) :: d1
   COMPLEX(C_FLOAT_COMPLEX) :: c1
   CHARACTER(KIND=C_CHAR) :: str(5)
 END TYPE

matches the following struct declaration in C

 
 struct {
   int i1, i2;
   /* Note: "char" might be signed or unsigned.  */
   signed char i3;
   double d1;
   float _Complex c1;
   char str[5];
 } myType;

Derived types with the C binding attribute shall not have the sequence attribute, type parameters, the extends attribute, nor type-bound procedures. Every component must be of interoperable type and kind and may not have the pointer or allocatable attribute. The names of the variables are irrelevant for interoperability.

As there exist no direct Fortran equivalents, neither unions nor structs with bit field or variable-length array members are interoperable.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.1.3 Interoperable Global Variables

Variables can be made accessible from C using the C binding attribute, optionally together with specifying a binding name. Those variables have to be declared in the declaration part of a MODULE, be of interoperable type, and have neither the pointer nor the allocatable attribute.

 
  MODULE m
    USE myType_module
    USE ISO_C_BINDING
    integer(C_INT), bind(C, name="_MyProject_flags") :: global_flag
    type(myType), bind(C) :: tp
  END MODULE

Here, _MyProject_flags is the case-sensitive name of the variable as seen from C programs while global_flag is the case-insensitive name as seen from Fortran. If no binding name is specified, as for tp, the C binding name is the (lowercase) Fortran binding name. If a binding name is specified, only a single variable may be after the double colon. Note of warning: You cannot use a global variable to access errno of the C library as the C standard allows it to be a macro. Use the IERRNO intrinsic (GNU extension) instead.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.1.4 Interoperable Subroutines and Functions

Subroutines and functions have to have the BIND(C) attribute to be compatible with C. The dummy argument declaration is relatively straightforward. However, one needs to be careful because C uses call-by-value by default while Fortran behaves usually similar to call-by-reference. Furthermore, strings and pointers are handled differently. Note that only explicit size and assumed-size arrays are supported but not assumed-shape or allocatable arrays.

To pass a variable by value, use the VALUE attribute. Thus the following C prototype

 
int func(int i, int *j)

matches the Fortran declaration

 
  integer(c_int) function func(i,j)
    use iso_c_binding, only: c_int
    integer(c_int), VALUE :: i
    integer(c_int) :: j

Note that pointer arguments also frequently need the VALUE attribute, see Working with Pointers.

Strings are handled quite differently in C and Fortran. In C a string is a NUL-terminated array of characters while in Fortran each string has a length associated with it and is thus not terminated (by e.g. NUL). For example, if one wants to use the following C function,

 
  #include <stdio.h>
  void print_C(char *string) /* equivalent: char string[]  */
  {
     printf("%s\n", string);
  }

to print "Hello World" from Fortran, one can call it using

 
  use iso_c_binding, only: C_CHAR, C_NULL_CHAR
  interface
    subroutine print_c(string) bind(C, name="print_C")
      use iso_c_binding, only: c_char
      character(kind=c_char) :: string(*)
    end subroutine print_c
  end interface
  call print_c(C_CHAR_"Hello World"//C_NULL_CHAR)

As the example shows, one needs to ensure that the string is NUL terminated. Additionally, the dummy argument string of print_C is a length-one assumed-size array; using character(len=*) is not allowed. The example above uses c_char_"Hello World" to ensure the string literal has the right type; typically the default character kind and c_char are the same and thus "Hello World" is equivalent. However, the standard does not guarantee this.

The use of strings is now further illustrated using the C library function strncpy, whose prototype is

 
  char *strncpy(char *restrict s1, const char *restrict s2, size_t n);

The function strncpy copies at most n characters from string s2 to s1 and returns s1. In the following example, we ignore the return value:

 
  use iso_c_binding
  implicit none
  character(len=30) :: str,str2
  interface
    ! Ignore the return value of strncpy -> subroutine
    ! "restrict" is always assumed if we do not pass a pointer
    subroutine strncpy(dest, src, n) bind(C)
      import
      character(kind=c_char),  intent(out) :: dest(*)
      character(kind=c_char),  intent(in)  :: src(*)
      integer(c_size_t), value, intent(in) :: n
    end subroutine strncpy
  end interface
  str = repeat('X',30) ! Initialize whole string with 'X'
  call strncpy(str, c_char_"Hello World"//C_NULL_CHAR, &
               len(c_char_"Hello World",kind=c_size_t))
  print '(a)', str ! prints: "Hello WorldXXXXXXXXXXXXXXXXXXX"
  end

The intrinsic procedures are described in Intrinsic Procedures.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.1.5 Working with Pointers

C pointers are represented in Fortran via the special opaque derived type type(c_ptr) (with private components). Thus one needs to use intrinsic conversion procedures to convert from or to C pointers. For example,

 
  use iso_c_binding
  type(c_ptr) :: cptr1, cptr2
  integer, target :: array(7), scalar
  integer, pointer :: pa(:), ps
  cptr1 = c_loc(array(1)) ! The programmer needs to ensure that the
                          ! array is contiguous if required by the C
                          ! procedure
  cptr2 = c_loc(scalar)
  call c_f_pointer(cptr2, ps)
  call c_f_pointer(cptr2, pa, shape=[7])

When converting C to Fortran arrays, the one-dimensional SHAPE argument has to be passed.

If a pointer is a dummy-argument of an interoperable procedure, it usually has to be declared using the VALUE attribute. void* matches TYPE(C_PTR), VALUE, while TYPE(C_PTR) alone matches void**.

Procedure pointers are handled analogously to pointers; the C type is TYPE(C_FUNPTR) and the intrinsic conversion procedures are C_F_PROCPOINTER and C_FUNLOC.

Let's consider two examples of actually passing a procedure pointer from C to Fortran and vice versa. Note that these examples are also very similar to passing ordinary pointers between both languages. First, consider this code in C:

 
/* Procedure implemented in Fortran.  */
void get_values (void (*)(double));

/* Call-back routine we want called from Fortran.  */
void
print_it (double x)
{
  printf ("Number is %f.\n", x);
}

/* Call Fortran routine and pass call-back to it.  */
void
foobar ()
{
  get_values (&print_it);
}

A matching implementation for get_values in Fortran, that correctly receives the procedure pointer from C and is able to call it, is given in the following MODULE:

 
MODULE m
  IMPLICIT NONE

  ! Define interface of call-back routine.
  ABSTRACT INTERFACE
    SUBROUTINE callback (x)
      USE, INTRINSIC :: ISO_C_BINDING
      REAL(KIND=C_DOUBLE), INTENT(IN), VALUE :: x
    END SUBROUTINE callback
  END INTERFACE

CONTAINS

  ! Define C-bound procedure.
  SUBROUTINE get_values (cproc) BIND(C)
    USE, INTRINSIC :: ISO_C_BINDING
    TYPE(C_FUNPTR), INTENT(IN), VALUE :: cproc

    PROCEDURE(callback), POINTER :: proc

    ! Convert C to Fortran procedure pointer.
    CALL C_F_PROCPOINTER (cproc, proc)

    ! Call it.
    CALL proc (1.0_C_DOUBLE)
    CALL proc (-42.0_C_DOUBLE)
    CALL proc (18.12_C_DOUBLE)
  END SUBROUTINE get_values

END MODULE m

Next, we want to call a C routine that expects a procedure pointer argument and pass it a Fortran procedure (which clearly must be interoperable!). Again, the C function may be:

 
int
call_it (int (*func)(int), int arg)
{
  return func (arg);
}

It can be used as in the following Fortran code:

 
MODULE m
  USE, INTRINSIC :: ISO_C_BINDING
  IMPLICIT NONE

  ! Define interface of C function.
  INTERFACE
    INTEGER(KIND=C_INT) FUNCTION call_it (func, arg) BIND(C)
      USE, INTRINSIC :: ISO_C_BINDING
      TYPE(C_FUNPTR), INTENT(IN), VALUE :: func
      INTEGER(KIND=C_INT), INTENT(IN), VALUE :: arg
    END FUNCTION call_it
  END INTERFACE

CONTAINS

  ! Define procedure passed to C function.
  ! It must be interoperable!
  INTEGER(KIND=C_INT) FUNCTION double_it (arg) BIND(C)
    INTEGER(KIND=C_INT), INTENT(IN), VALUE :: arg
    double_it = arg + arg
  END FUNCTION double_it

  ! Call C function.
  SUBROUTINE foobar ()
    TYPE(C_FUNPTR) :: cproc
    INTEGER(KIND=C_INT) :: i

    ! Get C procedure pointer.
    cproc = C_FUNLOC (double_it)

    ! Use it.
    DO i = 1_C_INT, 10_C_INT
      PRINT *, call_it (cproc, i)
    END DO
  END SUBROUTINE foobar

END MODULE m

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.1.6 Further Interoperability of Fortran with C

Assumed-shape and allocatable arrays are passed using an array descriptor (dope vector). The internal structure of the array descriptor used by GNU Fortran is not yet documented and will change. There will also be a Technical Report (TR 29113) which standardizes an interoperable array descriptor. Until then, you can use the Chasm Language Interoperability Tools, http://chasm-interop.sourceforge.net/, which provide an interface to GNU Fortran's array descriptor.

The technical report 29113 will presumably also include support for C-interoperable OPTIONAL and for assumed-rank and assumed-type dummy arguments. However, the TR has neither been approved nor implemented in GNU Fortran; therefore, these features are not yet available.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.2 GNU Fortran Compiler Directives

The Fortran standard standard describes how a conforming program shall behave; however, the exact implementation is not standardized. In order to allow the user to choose specific implementation details, compiler directives can be used to set attributes of variables and procedures which are not part of the standard. Whether a given attribute is supported and its exact effects depend on both the operating system and on the processor; see (gcc)Top section `C Extensions' in Using the GNU Compiler Collection (GCC) for details.

For procedures and procedure pointers, the following attributes can be used to change the calling convention:

Besides changing the calling convention, the attributes also influence the decoration of the symbol name, e.g., by a leading underscore or by a trailing at-sign followed by the number of bytes on the stack. When assigning a procedure to a procedure pointer, both should use the same calling convention.

On some systems, procedures and global variables (module variables and COMMON blocks) need special handling to be accessible when they are in a shared library. The following attributes are available:

The attributes are specified using the syntax

!GCC$ ATTRIBUTES attribute-list :: variable-list

where in free-form source code only whitespace is allowed before !GCC$ and in fixed-form source code !GCC$, cGCC$ or *GCC$ shall start in the first column.

For procedures, the compiler directives shall be placed into the body of the procedure; for variables and procedure pointers, they shall be in the same declaration part as the variable or procedure pointer.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.3 Non-Fortran Main Program

Even if you are doing mixed-language programming, it is very likely that you do not need to know or use the information in this section. Since it is about the internal structure of GNU Fortran, it may also change in GCC minor releases.

When you compile a PROGRAM with GNU Fortran, a function with the name main (in the symbol table of the object file) is generated, which initializes the libgfortran library and then calls the actual program which uses the name MAIN__, for historic reasons. If you link GNU Fortran compiled procedures to, e.g., a C or C++ program or to a Fortran program compiled by a different compiler, the libgfortran library is not initialized and thus a few intrinsic procedures do not work properly, e.g. those for obtaining the command-line arguments.

Therefore, if your PROGRAM is not compiled with GNU Fortran and the GNU Fortran compiled procedures require intrinsics relying on the library initialization, you need to initialize the library yourself. Using the default options, gfortran calls _gfortran_set_args and _gfortran_set_options. The initialization of the former is needed if the called procedures access the command line (and for backtracing); the latter sets some flags based on the standard chosen or to enable backtracing. In typical programs, it is not necessary to call any initialization function.

If your PROGRAM is compiled with GNU Fortran, you shall not call any of the following functions. The libgfortran initialization functions are shown in C syntax but using C bindings they are also accessible from Fortran.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.3.1 _gfortran_set_args -- Save command-line arguments

Description:

_gfortran_set_args saves the command-line arguments; this initialization is required if any of the command-line intrinsics is called. Additionally, it shall be called if backtracing is enabled (see _gfortran_set_options).

Syntax:

void _gfortran_set_args (int argc, char *argv[])

Arguments:

argc

number of command line argument strings

argv

the command-line argument strings; argv[0] is the pathname of the executable itself.

Example:
 
int main (int argc, char *argv[])
{
  /* Initialize libgfortran.  */
  _gfortran_set_args (argc, argv);
  return 0;
}

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.3.2 _gfortran_set_options -- Set library option flags

Description:

_gfortran_set_options sets several flags related to the Fortran standard to be used, whether backtracing or core dumps should be enabled and whether range checks should be performed. The syntax allows for upward compatibility since the number of passed flags is specified; for non-passed flags, the default value is used. See also see section Options for code generation conventions. Please note that not all flags are actually used.

Syntax:

void _gfortran_set_options (int num, int options[])

Arguments:

num

number of options passed

argv

The list of flag values

option flag list:

option[0]

Allowed standard; can give run-time errors if e.g. an input-output edit descriptor is invalid in a given standard. Possible values are (bitwise or-ed) GFC_STD_F77 (1), GFC_STD_F95_OBS (2), GFC_STD_F95_DEL (4), GFC_STD_F95 (8), GFC_STD_F2003 (16), GFC_STD_GNU (32), GFC_STD_LEGACY (64), GFC_STD_F2008 (128), and GFC_STD_F2008_OBS (256). Default: GFC_STD_F95_OBS | GFC_STD_F95_DEL | GFC_STD_F95 | GFC_STD_F2003 | GFC_STD_F2008 | GFC_STD_F2008_OBS | GFC_STD_F77 | GFC_STD_GNU | GFC_STD_LEGACY.

option[1]

Standard-warning flag; prints a warning to standard error. Default: GFC_STD_F95_DEL | GFC_STD_LEGACY.

option[2]

If non zero, enable pedantic checking. Default: off.

option[3]

If non zero, enable core dumps on run-time errors. Default: off.

option[4]

If non zero, enable backtracing on run-time errors. Default: off. Note: Installs a signal handler and requires command-line initialization using _gfortran_set_args.

option[5]

If non zero, supports signed zeros. Default: enabled.

option[6]

Enables run-time checking. Possible values are (bitwise or-ed): GFC_RTCHECK_BOUNDS (1), GFC_RTCHECK_ARRAY_TEMPS (2), GFC_RTCHECK_RECURSION (4), GFC_RTCHECK_DO (16), GFC_RTCHECK_POINTER (32). Default: disabled.

option[7]

If non zero, range checking is enabled. Default: enabled. See -frange-check (see section Options for code generation conventions).

Example:
 
  /* Use gfortran 4.5 default options.  */
  static int options[] = {68, 255, 0, 0, 0, 1, 0, 1};
  _gfortran_set_options (8, &options);

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.3.3 _gfortran_set_convert -- Set endian conversion

Description:

_gfortran_set_convert set the representation of data for unformatted files.

Syntax:

void _gfortran_set_convert (int conv)

Arguments:

conv

Endian conversion, possible values: GFC_CONVERT_NATIVE (0, default), GFC_CONVERT_SWAP (1), GFC_CONVERT_BIG (2), GFC_CONVERT_LITTLE (3).

Example:
 
int main (int argc, char *argv[])
{
  /* Initialize libgfortran.  */
  _gfortran_set_args (argc, argv);
  _gfortran_set_convert (1);
  return 0;
}

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.3.4 _gfortran_set_record_marker -- Set length of record markers

Description:

_gfortran_set_record_marker sets the length of record markers for unformatted files.

Syntax:

void _gfortran_set_record_marker (int val)

Arguments:

val

Length of the record marker; valid values are 4 and 8. Default is 4.

Example:
 
int main (int argc, char *argv[])
{
  /* Initialize libgfortran.  */
  _gfortran_set_args (argc, argv);
  _gfortran_set_record_marker (8);
  return 0;
}

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.3.5 _gfortran_set_fpe -- Set when a Floating Point Exception should be raised

Description:

_gfortran_set_fpe sets the IEEE exceptions for which a Floating Point Exception (FPE) should be raised. On most systems, this will result in a SIGFPE signal being sent and the program being interrupted.

Syntax:

void _gfortran_set_fpe (int val)

Arguments:

option[0]

IEEE exceptions. Possible values are (bitwise or-ed) zero (0, default) no trapping, GFC_FPE_INVALID (1), GFC_FPE_DENORMAL (2), GFC_FPE_ZERO (4), GFC_FPE_OVERFLOW (8), GFC_FPE_UNDERFLOW (16), and GFC_FPE_PRECISION (32).

Example:
 
int main (int argc, char *argv[])
{
  /* Initialize libgfortran.  */
  _gfortran_set_args (argc, argv);
  /* FPE for invalid operations such as SQRT(-1.0).  */
  _gfortran_set_fpe (1);
  return 0;
}

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.3.6 _gfortran_set_max_subrecord_length -- Set subrecord length

Description:

_gfortran_set_max_subrecord_length set the maximum length for a subrecord. This option only makes sense for testing and debugging of unformatted I/O.

Syntax:

void _gfortran_set_max_subrecord_length (int val)

Arguments:

val

the maximum length for a subrecord; the maximum permitted value is 2147483639, which is also the default.

Example:
 
int main (int argc, char *argv[])
{
  /* Initialize libgfortran.  */
  _gfortran_set_args (argc, argv);
  _gfortran_set_max_subrecord_length (8);
  return 0;
}

[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated on March, 29 2011 using texi2html 1.76.