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_FUNPTR
Type(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 ENUMis 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.