# CFI_establish

C function prototype: Establishes a C descriptor.

    int CFI_establish(CFI_cdesc_t *dv, void *base_addr,
                      CFI_attribute_t attribute,
                      CFI_type_t type, size_t elem_len,
                      CFI_rank_t rank,
                      const CFI_index_t extents[]);

Formal Parameters:

dv | The address of a data object large enough to hold a C descriptor of the rank specified by rank. It must not have the same value as either a C formal parameter that corresponds to a Fortran actual argument or a C actual argument that corresponds to a Fortran dummy argument. It must not be the address of a C descriptor that describes an allocated allocatable object.
base_addr | A null pointer or the base address of the object to be described. If it is not a null pointer, it must be the address of a contiguous storage sequence that is appropriately aligned for an object of the type specified by type.
attribute | One of the attribute codes in Table "Macros for attribute codes" in C Typedefs and Macros for interoperability. If it is `CFI_attribute_allocatable`, base_addr must be a null pointer.
type | One of the type codes in Table "Macros for type codes" in C Typedefs and Macros for interoperability.
elem_len | If the type is `CFI_type_struct`, `CFI_type_other`, or a Fortran character type code, elem_len must be greater than zero and equal to the storage size in bytes of an element of the object. Otherwise, type is ignored.
rank | A value in the range 0 ≤ rank ≤ `CFI_MAX_RANK`. It specifies the rank of the object.
extents | This is ignored if rank is equal to zero or if base_addr is a null pointer. Otherwise, it must be the address of an array with rank elements; the value of each element must be nonnegative, and extents[i] specifies the extent of dimension i of the object.

## Description

Successful execution of CFI_establish updates the object with the address dv to be an established C descriptor for a nonallocatable nonpointer data object of known shape, an unallocated allocatable object, or a data pointer.

If base_addr is not a null pointer, it is the address for a nonallocatable entity that is a scalar or a contiguous array. If the attribute argument has the value `CFI_attribute_pointer`, the lower bounds of the object described by dv are set to zero. If base_addr is a null pointer, the established C descriptor is for an unallocated allocatable, a disassociated pointer, or is a C descriptor that has the attribute `CFI_attribute_other` but does not describe a data object. If base_addr is the C address of a Fortran data object, the type and elem_len arguments must be consistent with the type and type parameters of the Fortran data object.

The remaining properties of the object are given by the other arguments.

CFI_establish is used to initialize a C descriptor declared in C with `CFI_CDESC_T` before passing it to any other functions as an actual argument, in order to set the rank, attribute, type and element length.

A C descriptor with attribute `CFI_attribute_other` and a base_addr that is a null pointer can be used as the argument result in calls to `CFI_section` or `CFI_select_part`, which will produce a C descriptor for a nonallocatable nonpointer data object.

If an error is detected, the object with the address dv is not modified.

## Result Value

The result is an error indicator.

## Example

The following code fragment establishes a C descriptor for an unallocated rank-one allocatable array that can be passed to Fortran for allocation there:

    CFI_rank_t rank;
    CFI_CDESC_T(1) field;
    int ind;
    rank = 1;
    ind = CFI_establish((CFI_cdesc_t *)&field, NULL,
    CFI_attribute_allocatable,
    CFI_type_double, 0, rank, NULL);

If the following Fortran type definition is specified:

    TYPE, BIND(C) :: T
    REAL(C_DOUBLE) :: X
    COMPLEX(C_DOUBLE_COMPLEX) :: Y
    END TYPE

and a Fortran subprogram that has an assumed-shape dummy argument of type T, the following code fragment creates a descriptor `a_fortran` for an array of size 100 that can be used as the actual argument in an invocation of the subprogram from C:

    typedef struct {double x; double _Complex y;} t;
    t a_c[100];
    CFI_CDESC_T(1) a_fortran;
    int ind;
    CFI_index_t extent[1];

    extent[0] = 100;
    ind = CFI_establish((CFI_cdesc_t *)&a_fortran, a_c,
    CFI_attribute_other,
    CFI_type_struct, sizeof(t), 1, extent);

Parent topic: C to D

## See Also

C Structures Typedefs and Macros for interoperability
Interoperating with arguments using C descriptors