# Interoperating with arguments using C descriptors

These are facilities for interoperable procedure interfaces that specify dummy arguments that are assumed-shape arrays, have assumed character length, or have the ALLOCATABLE, POINTER, or OPTIONAL attributes.

## Assumed-rank

An assumed-rank object is a dummy variable whose rank is assumed from its actual argument. This facilitates interoperability with C functions that can accept arguments of arbitrary rank. The intrinsic function, RANK, can be used to obtain the rank of an assumed-rank variable.

A procedure must have an explicit interface if it has a dummy argument that is assumed-rank.

The SHAPE, SIZE, and UBOUND intrinsic functions are defined for an assumed-rank array that is associated with an assumed-size array.

An assumed-rank dummy argument may correspond to an actual argument of any rank. If the actual argument has rank zero, the dummy argument has rank zero; the shape is a zero-sized array and the LBOUND and UBOUND intrinsic functions, with no DIM argument, return zero-sized arrays. If the actual argument has rank greater than zero, the rank and extents of the dummy argument are assumed from the actual argument, including no final extent for an assumed-size array. If the actual argument is an array and the dummy argument has the ALLOCATABLE or POINTER attribute, the bounds of the dummy argument are assumed from the actual argument.

## Assumed-type

An assumed-type object is a dummy variable declared as `TYPE(*)`. This simplifies interoperability with C formal parameters of type `(void *)`.

An explicit interface is required for a procedure that has a dummy argument that is assumed-type because an assumed-type dummy argument is polymorphic.

An assumed-type dummy argument must not correspond to an actual argument that is of derived type with type parameters, type-bound procedures, or final subroutines.

## CFI_cdesc

A C descriptor is a C structure of type CFI_cdesc that is defined in the file ISO_Fortran_binding.h.

## Restrictions for BIND(C)

If BIND(C) is specified for a procedure, each dummy argument must be an interoperable procedure or a variable that is interoperable, assumed shape, assumed rank, assumed type, of assumed character length, or has the ALLOCATABLE or POINTER attribute. If BIND(C)is specified for a function, the function result must be an interoperable scalar variable.

A dummy argument of a procedure that is BIND(C) must not have both the OPTIONAL and VALUE attributes.

A variable that is a dummy argument of a procedure that is BIND(C) must be of interoperable type or assumed type.

A coarray shall not be a dummy argument of a BIND(C) procedure.

The ALLOCATABLE or POINTER attribute must not be specified for a default-initialized dummy argument of a BIND(C) procedure.

## Further Requirements

Variables with the ASYNCHRONOUS attribute can be used for asynchronous communications between Fortran and C procedures.

When a Fortran procedure that has an INTENT (OUT) allocatable dummy argument is invoked by a C function, and the actual argument in the C function is the address of a C descriptor that describes an allocated allocatable variable, the variable is deallocated on entry to the Fortran procedure. When a C function is invoked from a Fortran procedure via an interface with an INTENT (OUT) allocatable dummy argument, and the actual argument in the reference to the C function is an allocated allocatable variable, the variable is deallocated on invocation (before execution of the C function begins).

## ISO_Fortran_binding.h

The types, macros, and functions declared in ISO_Fortran_binding.h can be used by a C function to interpret C descriptors and allocate and deallocate objects represented by C descriptors. These provide a means to specify a C prototype that interoperates with a Fortran interface that has an allocatable, assumed character length, assumed-rank, assumed-shape, or data pointer dummy argument.

The ISO_Fortran_binding.h is a C header file that contains these definitions:

- The C structures CFI_cdesc_t and CFI_dim_t
- The typedef definitions for CFI_attribute_t, CFI_index_t, CFI_rank_t, and CFI_type_t
- The macro CFI_CDESC_T and macro definitions that expand to integer constants with various useful values
- The C function prototypes or macro definitions for CFI_address, CFI_allocate, CFI_deallocate, CFI_establish, CFI_is_contiguous, CFI_section, CFI_select_part, and CFI_setpointer. Some of these functions return an error indicator; this is an integer value that indicates whether an error condition was detected. The value zero CFI_SUCCESS indicates that no error condition was detected, and a nonzero value indicates which error condition was detected. The "Macros and typedefs in ISO_Fortran_binding.h" section lists the standard error conditions and the macro names for their corresponding error codes.

  In function arguments representing subscripts, bounds, extents, or strides, the ordering of the elements is the same as the ordering of the elements of the dim member of a C descriptor.

## Restrictions on C functions interoperating with Fortran procedures

Any C function inter-operating with Fortran procedures must meet these restrictions:

- A C descriptor shall not be initialized, updated, or copied other than by calling the functions in ISO_Fortran_binding.h.
- If the address of a C descriptor is a formal parameter that corresponds to a Fortran actual argument or is a C actual argument that corresponds to a Fortran dummy argument,
  - the C descriptor shall not be modified if either the corresponding dummy argument in the Fortran interface has the INTENT(IN) attribute or the C descriptor is for a nonallocatable nonpointer object, and
  - the base_addr member of the C descriptor shall not be accessed before it is given a value if the corresponding dummy argument in the Fortran interface has the POINTER and INTENT(OUT) attributes.

  In this context, modification refers to any change to the location or contents of the C descriptor, including establishing and updating. The intent of these restrictions is that the C descriptors will remain intact at all times that they are accessible to an active Fortran procedure, so that the Fortran code is not required to copy them.

- Within a C function, an allocatable object shall be allocated or deallocated only by execution of the CFI_allocate and CFI_deallocate functions. A Fortran pointer can become associated with a target by execution of the CFI allocate function.
- Calling CFI_allocate or CFI_deallocate for a C descriptor changes the allocation status of the Fortran variable it describes and causes the allocation status of any associated allocatable variable to change accordingly.
- If the address of an object is the value of a formal parameter that corresponds to a nonpointer dummy argument in a BIND(C) interface, then
  - if the dummy argument has the INTENT (IN) attribute, the object must not be defined or become undefined, and
  - if the dummy argument has the INTENT (OUT) attribute, the object must not be referenced before it is defined.
- When a Fortran object is deallocated, or execution of its host function is completed, or its association status becomes undefined, all C descriptors and C pointers to any part of it become undefined, and any further use of them is undefined behavior.
- A C descriptor whose address is a formal parameter that corresponds to a Fortran dummy argument becomes undefined on return from a call to the function from Fortran. If the dummy argument does not have either the TARGET or ASYNCHRONOUS attribute, all C pointers to any part of the object described by the C descriptor become undefined on return from the call, and any further use of them is undefined behavior.
- When a Fortran object is deallocated, or execution of its host function is completed, or its association status becomes undefined, all C descriptors and C pointers to any part of it become undefined, and any further use of them is undefined behavior.
- If the address of a C descriptor is passed as an actual argument to a Fortran procedure, the C lifetime of the C descriptor shall not end before the return from the procedure call.
- If an object is passed to a Fortran procedure as a nonallocatable, nonpointer dummy argument, its lifetime shall not end before the return from the procedure call.
- If the lifetime of a C descriptor for an allocatable object that was established by C ends before the program exits, the object shall be unallocated at that time.
- If a Fortran pointer becomes associated with a C object, the association status of the Fortran pointer becomes undefined when the lifetime of the C object ends.

Parent topic: Standard Tools for Interoperability

## See Also

C Structures, Typedefs, and Macros for Interoperability