float), a named constant for use as a KIND
parameter for the corresponding Fortran type,
C_PTR and C_FUNPTR for interoperating with C object
pointers and function pointers,
INTEGER for integral types and REAL for
floating-point types.
This is shown in the table below.
Note that only c_int is guaranteed to be available; if there is no
compatible type the value will be negative.
| C type | Fortran type and kind |
_Bool | LOGICAL(c_bool) |
char | CHARACTER(c_char) — For characters as text. |
double | REAL(c_double) |
double _Complex | COMPLEX(c_double_complex) or COMPLEX(c_double) |
float | REAL(c_float) |
float _Complex | COMPLEX(c_float_complex) or COMPLEX(c_float) |
int | INTEGER(c_int) |
int16_t | INTEGER(c_int16_t) |
int32_t | INTEGER(c_int32_t) |
int64_t | INTEGER(c_int64_t) |
int8_t | INTEGER(c_int8_t) |
int_fast16_t | INTEGER(c_int_fast16_t) |
int_fast32_t | INTEGER(c_int_fast32_t) |
int_fast64_t | INTEGER(c_int_fast64_t) |
int_fast8_t | INTEGER(c_int_fast8_t) |
int_least16_t | INTEGER(c_int_least16_t) |
int_least32_t | INTEGER(c_int_least32_t) |
int_least64_t | INTEGER(c_int_least64_t) |
int_least8_t | INTEGER(c_int_least8_t) |
intmax_t | INTEGER(c_intmax_t) |
intptr_t | INTEGER(c_intptr_t) |
long | INTEGER(c_long) |
long double | REAL(c_long_double) |
long double _Complex | COMPLEX(c_long_double_complex) or COMPLEX(c_long_double) |
long long | INTEGER(c_long_long) |
short | INTEGER(c_short) |
signed char | INTEGER(c_signed_char) — For characters as integers. |
size_t | INTEGER(c_size_t) |
C_PTR and C_FUNPTRType(c_ptr) and
Type(c_funptr).
Type(c_ptr) is essentially equivalent to the C void *;
i.e. it can contain any object pointer.
Type(c_funptr) does the same thing for function pointers.
For C arguments like ‘int *’, you don't need to use
Type(c_ptr), you can just use a normal dummy argument (in this case of
type Integer(c_int)) without the VALUE attribute.
However, for more complicated pointer arguments such as pointer to
pointer, or for variables or components that are pointers, you need to use
Type(c_ptr).
Null pointer constants of both Type(c_ptr) and Type(c_funptr) are
provided: these are named C_NULL_PTR and C_NULL_FUNPTR respectively.
To create a Type(c_ptr) value, the function C_LOC(X) is used on
a Fortran object X (and X must have the TARGET attribute).
Furthermore, the Fortran object cannot be polymorphic, a zero-sized array,
an assumed-size array, or an array pointer.
To create a Type(c_funptr) value, the function C_FUNLOC is used
on a procedure; this procedure must have the BIND(C) attribute.
To test whether a Type(c_ptr) or Type(c_funptr) is null, the
C_ASSOCIATED(C_PTR_1) function can be used; it returns .TRUE. if
and only if C_PTR_1 is not null.
Two Type(c_ptr) or two Type(c_funptr) values can be compared
using C_ASSOCIATED(C_PTR_1,C_PTR_2) function; it returns .TRUE.
if and only if C_PTR_1 contains the same C address as C_PTR_2.
The subroutine C_F_POINTER(CPTR,FPTR) converts the TYPE(C_PTR)
value CPTR to the scalar Fortran pointer FPTR; the latter can
have any type (including non-interoperable types) but must not be polymorphic.
The subroutine C_F_POINTER(CPTR,FPTR,SHAPE) converts a
TYPE(C_PTR) value into the Fortran array pointer FPTR, where
SHAPE is an integer array of rank 1, with the same number of elements as
the rank of FPTR; the lower bounds of the resultant FPTR will all
be 1.
The subroutine C_F_PROCPOINTER(CPTR,FPTR) is provided. This converts
the TYPE(C_FUNPTR) CPTR to the Fortran procedure pointer FPTR.
Note that in all the conversion cases it is up to the programmer to use the correct type and other information.
struct types can be created by
giving the type the BIND(C) attribute, e.g.
TYPE,BIND(C) :: mytypeThe components of a BIND(C) type must have types corresponding to C types, and cannot be pointers or allocatables. Furthermore, a BIND(C) type cannot be a
SEQUENCE type (it already
acts like a SEQUENCE type), cannot have type-bound procedures,
cannot have final procedures,
and cannot be extended.
BIND(C) attribute.
Such a variable can only be declared in a module, and cannot be in a
COMMON block.
By default, the C name of the variable is the Fortran name converted to
all lowercase characters; a different name may be specified with the
NAME= clause, e.g.
INTEGER,BIND(C,NAME="StrangelyCapiTalisedCName") :: xWithin Fortran code, the variable is referred to by its Fortran name, not its C name.
NAME= clause.
For example
SUBROUTINE sub() BIND(C,NAME='Sub') ...Again, the C name is for use only from C, the Fortran name is used from Fortran. If the C name is all blanks (or a zero-length string), there is no C name. Such a procedure can still be called from C via a procedure pointer (i.e. by assigning it to a
TYPE(C_FUNPTR) variable).
A BIND(C) procedure must be a module procedure or external procedure
with an explicit interface; it cannot be an internal procedure or statement
function.
A BIND(C) procedure may be a subroutine or a scalar function with a type
corresponding to a C type.
Each dummy argument must be a variable whose type corresponds to a C type,
and cannot be allocatable, assumed-shape, optional or a pointer.
If the dummy argument does not have the VALUE attribute, it
corresponds to a C dummy argument that is a pointer.
Here is an example of a Fortran procedure together with its reference from C:
SUBROUTINE find_minmax(x,n,max,min) BIND(C,NAME='FindMinMax') USE iso_c_binding REAL(c_double) x(*),max,min INTEGER(c_int),VALUE :: n INTRINSIC maxval,minval max = MAXVAL(x(:n)) min = MINVAL(x(:n)) END extern void FindMinMax(double *x,int n,double *maxval,double *minval); double x[100],xmax,xmin; int n; ... FindMinMax(x,n,&xmax,&xmin);
This also allows C procedures to be called from Fortran, by describing the C procedure to be called in an interface block. Here is an example:
/* This is the prototype for a C library function from 4.3BSD. */
int getloadavg(double loadavg[],int nelem);
PROGRAM show_loadavg
USE iso_c_binding
INTERFACE
FUNCTION getloadavg(loadavg,nelem) BIND(C)
IMPORT c_double,c_int
REAL(c_double) loadavg(*)
INTEGER(c_int),VALUE :: nelem
INTEGER(c_int) getloadavg
END FUNCTION
END INTERFACE
REAL(c_double) averages(3)
IF (getloadavg(averages,3)/=3) THEN
PRINT *,'Unexpected error'
ELSE
PRINT *,'Load averages:',averages
END IF
END
enum declaration. For example,
ENUM,BIND(C)
ENUMERATOR :: open_door=4, close_door=17
ENUMERATOR :: lock_door
END ENUM
is equivalent to
enum {
open_door=4, close_door=17, lock_door
};
If a value is not given for one of the enumerators, it will be one greater than
the previous value (or zero if it is the first enumerator in the list).
The kind used for a particular set of enumerators can be discovered by using the
KIND intrinsic on one of the enumerators.
Note that the BIND(C) clause is required; the standard only defines
enumerations for interoperating with C.