# C Structures, Typedefs, and Macros for Interoperability

## The C structures CFI_dim_t and CFI_cdesc_t

CFI_dim_t is a typedef name for a C structure. This typedef is used to represent lower bound, extent, and memory stride information for one dimension of an array. CFI_dim_t contains at least the following members in any order:

- CFI_index_t lower_bound: The value of the lower bound for the dimension being described.

- CFI_index_t extent: The value is the number of elements in the dimension being described or -1 for the last dimension of an assumed-size array.

- CFI_index_t sm: The value is the memory stride for a dimension; this value is the difference in bytes between the addresses of successive elements in the dimension being described.

CFI_cdesc_t is a typedef name for a C structure, which contains a flexible array member. The first three members of the structure are base_addr, elem_len, and version in that order. The final member is dim. All other members must be between version and dim, in any order.

- `void * base_addr`: If the object Interoperating with arguments using C descriptors is an unallocated allocatable variable or a pointer that is disassociated, the value is a null pointer. If the object has zero size, the value is not a null pointer but is processor-11 dependent. Otherwise, the value is the base address of the object being described. The base address of a scalar is its C address. The base address of an array is the C address of the first element in Fortran array element order.

- `size_t elem_len`: If the object is a scalar, the value is the storage size in bytes of the object; otherwise, the value is the storage size in bytes of an element of the object.

- `int version`: The value is the value of CFI_VERSION in the source file ISO_Fortran_binding.h that defined the format and meaning of this C descriptor when the descriptor was established.

- `CFI_rank_t rank`: The value is the number of dimensions of the Fortran object being described; if the object is a scalar, the value is zero.

- `CFI_type_t type`: The value is the specifier for the type of the object. Each interoperable intrinsic C type has a specifier. Specifiers are also provided to indicate that the type of the object is an interoperable structure, or is unknown. The macros listed in the table below provide values that correspond to each type code specifier.

  Macros for Type Codes
  Macro name | C Type
  --- | ---
  CFI_type_signed_char | signed char
  CFI_type_short | short int
  CFI_type_int | int
  CFI_type_long | long int
  CFI_type_long_long | long long int
  CFI_type_size_t | size_t
  CFI_type_int8_t | int8_t
  CFI_type_int16_t | int16_t
  CFI_type_int32_t | int32_t
  CFI_type_int64_t | int64_t
  CFI_type_int_least8_t | int_least8_t
  CFI_type_int_least16_t | int_least16_t
  CFI_type_int_least32_t | int_least32_t
  CFI_type_int_least64_t | int_least64_t
  CFI_type_int_fast8_t | int_fast8_t
  CFI_type_int_fast16_t | int_fast16_t
  CFI_type_int_fast32_t | int_fast32_t
  CFI_type_int_fast64_t | int_fast64_t
  CFI_type_intmax_t | intmax_t
  CFI_type_intptr_t | intptr_t
  CFI_type_ptrdiff_t | ptrdiff_t
  CFI_type_float | float
  CFI_type_double | double
  CFI_type_long_double | long double
  CFI_type_float_Complex | float _Complex
  CFI_type_double_Complex | double _Complex
  CFI_type_long_double_Complex | long double _Complex
  CFI_type_Bool | _Bool
  CFI_type_char | char
  CFI_type_cptr | void *
  CFI_type_struct | interoperable C structure
  CFI_type_other | not otherwise specified

  - The value for CFI_type_other is negative and distinct from all other type specifiers.

  - CFI_type_struct specifies a C structure that is interoperable with a Fortran derived type; its value is positive and distinct from all other type specifiers.

  - If a C type is not interoperable with a Fortran type and kind supported by the Fortran processor, its macro evaluates to a negative value.

  - Otherwise, the value for an intrinsic type is positive.

- CFI_attribute_t attribute – The value is the value of an attribute code that indicates whether the object described is allocatable, a data pointer, or a nonallocatable, nonpointer data object. The values are nonnegative and distinct.

  The macros listed in the table below provide values that correspond to each attribute code.

  Macros for Attribute Codes
  Macro | Attribute code indicated
  --- | ---
  CFI_attribute_pointer | Data pointer object
  CFI_attribute_allocatable | Allocatable object
  CFI_attribute_other | Nonallocatable, nonpointer object

  - CFI_attribute_pointer specifies a data object with the Fortran POINTER attribute.

  - CFI_attribute_allocatable specifies an object with the Fortran ALLOCATABLE attribute.

  - CFI_attribute_other specifies a nonallocatable nonpointer object.

- CFI_dim_t dim – The number of elements in the dim array is equal to the rank of the object. Each element of the array contains the lower bound, extent, and memory stride information for the corresponding dimension of the Fortran object.

For a C descriptor of an array pointer or allocatable array, the value of the lower_bound member of each element of the dim member of the descriptor is determined by argument association, allocation, or pointer association. For a C descriptor of a nonallocatable nonpointer object, the value of the lower_bound member of each element of the dim member of the descriptor is zero.

In a C descriptor of an assumed-size array, the extent member of the last element of the dim member has the value -1. The value of elem_len for a Fortran CHARACTER object is equal to the character length times the number of bytes of a single character of that kind. If the kind is C_CHAR, this value will be equal to the character length.

## Macros and typedefs in ISO_Fortran_binding.h

Except for CFI_CDESC_T, each macro defined in ISO_Fortran_binding.h expands to an integer constant expression that is either a single token or a parenthesized expression that is suitable for use in `#if` preprocessing directives.

CFI_CDESC_T is a function-like macro that takes one argument: the rank of the C descriptor creates and evaluates to an unqualified type of suitable size and alignment for defining a variable to use as a C descriptor of that rank. The argument shall be an integer constant expression with a value that is greater than or equal to zero and less than or equal to CFI_MAX_RANK. A pointer to a variable declared using CFI_CDESC_T can be cast to `CFI_cdesc_t *`. A variable declared using CFI_CDESC_T must not have an initializer.

The CFI_CDESC_T macro provides the memory for a C descriptor. The address of an entity declared using the macro is not usable as an actual argument corresponding to a formal parameter of type `CFI_cdesc_t *` without an explicit cast.

CFI_index_t is a typedef name for a standard signed integer type capable of representing the result of subtracting two pointers.

The CFI_MAX_RANK macro has a value equal to the largest rank supported, i.e., 31. CFI_rank_t is a typedef name for a standard integer type capable of representing the largest supported rank.

The CFI_VERSION macro has a processor-dependent value that encodes the version of the ISO_Fortran_binding.h source file containing this macro. This value is increased if a new version of the source file is incompatible with the previous version.

CFI_attribute_t is a typedef name for a standard integer type capable of representing the values of the attribute codes.

CFI_type_t is a typedef name for a standard integer type capable of representing the values for the supported type specifiers.

The macros in the table below are for use as error codes. The macro CFI_SUCCESS is the integer constant 0. The value of each macro other than CFI_SUCCESS is nonzero and is different from the values of the other error code macros.

Macros for Error Codes
Macro name | Error condition
--- | ---
CFI_SUCCESS | No error detected.
CFI_ERROR_BASE_ADDR_NULL | The base address member of a C descriptor is a null pointer in a context that requires a non-null pointer value.
CFI_ERROR_BASE_ADDR_NOT_NULL | The base address member of a C descriptor is not a null pointer in a context that requires a null pointer value.
CFI_INVALID_ELEM_LEN | The value supplied for the element length member of a C descriptor is not valid.
CFI_INVALID_RANK | The value supplied for the rank member of a C descriptor is not valid.
CFI_INVALID_TYPE | The value supplied for the type member of a C descriptor is not valid.
CFI_INVALID_ATTRIBUTE | The value supplied for the attribute member of a C descriptor is not valid.
CFI_INVALID_EXTENT | The value supplied for the extent member of a CFI_dim_t structure is not valid.
CFI_INVALID_DESCRIPTOR | A C descriptor is invalid in some way.
CFI_ERROR_MEM_ALLOCATION | Memory allocation failed.
CFI_ERROR_OUT_OF_BOUNDS | A reference is out of bounds.

Parent topic: Standard Tools for Interoperability

## See Also

Interoperating with arguments using C descriptors