NAG Fortran Compiler, Release 7.2: Mixing Fortran and C

Navigation: Previous Up Next

## 12.1 Mixing Fortran and C

When mixing Fortran source code with C source code, without using the C interoperability features of Fortran 2003, the following points should be noted.

### 12.1.1 Naming Conventions

External procedure names, common block names, and the main program name are in lower case with an underscore appended (this is the same as the standard UNIX f77 for procedures and common blocks). The ‘`main`’ procedure is a wrapper which initialises the environment and calls the actual main program.

Module variables and module procedure names are formed by taking the module name (in lower case), appending ‘`_MP_`’ and then appending the entity's name (in lower case).

These conventions differ when the -compatible option is used. On Windows this causes external procedures and common blocks to be in upper case with no trailing underscore, while module entities have the module name in upper case instead of lower case (64-bit Windows is always -compatible). On most other platforms this option adds an extra underscore (after the one that is always added) for names that already had an underscore.

### 12.1.2 Initialisation and Termination

If the main program is not written in Fortran then either the initialisation routine

        __NAGf90_rts_init(int argc,char*argv[])

or the i/o initialisation routine

        __NAGf90_io_init(void)

should be called from C. The `__NAGf90_rts_init` routine initialises the Fortran floating-point environment as well as allowing command-line arguments to be accessed via the Fortran 2003 intrinsic functions and also via the `F90_UNIX` module.

Additionally, the program should be terminated with `__NAGf90_finish(int status)`, or alternatively `__NAGf90_io_finish(void)` may be called before the usual C termination routine to close all Fortran files and flush the Fortran i/o buffers (failing to do this might corrupt an output file that is still open).

### 12.1.3 Calling Conventions

The following sections describe in detail the calling conventions used by Fortran programs compiled with the NAG Fortran Compiler in C terms. This information is thus mostly useful to those wishing to mix Fortran and C code.

The conventions used for the Fortran 77 subset of Modern Fortran are compatible with the de facto UNIX f77 conventions (except for `COMPLEX` functions compiled without the -compatible option).

### 12.1.4 Data Types

Definitions of data types useful in communicating from C to Fortran are in the files `dope.h` and `nagfortran.h`, which are located in the compiler library directory (usually `/usr/local/lib/NAG_Fortran` on UNIX-like systems).

Fortran Data Type | Fortran Precision | C `typedef` name
INTEGER | 8 bits | Integer1
| 16 bits | Integer2
| 32 bits | Integer or Integer3
| 64 bits | Integer4
LOGICAL | 8 bits | Logical1
| 16 bits | Logical2
| 32 bits | Logical
| 64 bits | Logical4
REAL | half | __NAGf90_HReal
| single | float (keyword, not typedef)
| double | double (keyword, not typedef)
| quadruple (double-double) | DDReal
COMPLEX | half | __NAGf90_HComplex
| single | Complex
| double | DComplex
| quadruple (double-double) | DDComplex

#### 12.1.4.1 Pointers

Scalar non-polymorphic non-CHARACTER `POINTER` types are simply C pointers to the object.

An array `POINTER` is a dope vector describing the array pointed to. Unlike a simple address, these dope vectors are capable of directly describing non-contiguous array sections of contiguous arrays. See below (`__NAGf90_Dope`N and `__NAGf90_ChDope`N) for further details. Polymorphic dope vectors are `__NAGf90_NPDope`N except for `CLASS(*)` pointers which are `__NAGf90_CSDope`N. Interoperable dope vectors are `__NAGf90_CFI_Dope`N.

#### 12.1.4.2 Derived types

Fortran derived types are translated into C `struct`s. If `BIND(C)` or `SEQUENCE` is used, the order of the items within the struct is the same as the order within the derived type definition. Otherwise, the order of items is permuted to put larger types at the front of the struct so as to improve alignment and reduce storage; the C output code can be inspected to determine the ordering used.

#### 12.1.4.3 Supporting types

`Char`
  `unsigned char`
  Data type for default (single-byte) character storage.
`Char2`
  `unsigned short`
  Data type for 16-bit (JIS and UCS-2) character storage.
`Char4`
  `unsigned int`
  Data type for 32-bit (UCS-4) character storage.
`Substring`
  `struct { Char *addr; Chrlen len;}`
  Describes a single-byte (default) `CHARACTER` string; used for deferred-length default `CHARACTER` variables and as the return type of variable-length scalar non-`POINTER` default `CHARACTER` functions and all `POINTER` default `CHARACTER` functions.
`Substring2`
  `struct { Char2 *addr; Chrlen len;}`
  Describes a 16-bit (JIS or UCS-2) `CHARACTER` string; used for deferred-length 16-bit `CHARACTER` variables and as the return type of variable-length scalar non-`POINTER` 16-bit `CHARACTER` functions and all `POINTER` 16-bit `CHARACTER` functions.
`Substring4`
  `struct { Char4 *addr; Chrlen len;}`
  Describes a 32-bit ISO_10646 (UCS-4) `CHARACTER` string; used for deferred-length 32-bit `CHARACTER` variables and as the return type of variable-length scalar non-`POINTER` UCS-4 `CHARACTER` functions and all `POINTER` UCS-4 `CHARACTER` functions.
`Offset`
  `int`, `long` or `long long`
  An integer type for addressing and subscript calculations; this is `int` (32-bit) on 32-bit systems and small model 64-bit systems, and a 64-bit integer type on large model 64-bit systems.
`Chrlen`
  usually `int`, or `long long` on 64-bit Windows.
  An integer type for representing character length.
`Pointer`
  usually `char *`.
  A byte pointer used to refer to any type and for pointer arithmetic.
`Triplet`
  `struct { Offset extent,mult,lower;}`
  Contains the parameters of an array dimension. `extent` is the size of that dimension, `mult` is the stride (i.e., the distance between successive elements in bytes) and `lower` is the lower bound. It is a component of the `__NAGf90_Dope`N and `__NAGf90_ChDope`N structs.
`__NAGf90_Dope`N
  `struct { Pointer addr; Offset offset; Triplet dim[N];}`
  Dope vectors for all non-polymorphic non-`CHARACTER` arrays (including arrays of derived type). N is the rank and is from 1 to 7. `addr` is the address of the first element, `dim` describes each dimension and `offset` is the offset to add to the subscript calculation, i.e., `SUM(mult*lower)`. This is used as the return type for `POINTER` array functions; a pointer to it is used as the argument type for assumed-shape and `POINTER` array arguments.

  An array pointer which has been nullified has an `addr` field which is a null pointer; note that zero-sized arrays have an `addr` field which is not a null pointer.

`__NAGf90_ChDope`N
  `struct { Pointer addr; Chrlen len; Offset offset; Triplet dim[N];}`
  These are exactly the same as the `Dope`N structs with the addition of the `len` component which specifies the `CHARACTER` length.
`__NAGf90_ArrayTemp_type`
  `struct { type *addr; Offset extent[7];}`
  Describes a contiguous array of type, which is one of: `Integer1`, `Integer2`, `Integer`, `Integer4`, `Logical1`, `Logical2`, `Logical`, `Logical4`, `Real`, `Double`, `QReal`, `Complex`, `DComplex` or `QComplex`. It is used as the return type for non-`POINTER` array functions. Note that `extent` values after the rank of the array being described are undefined.
`__NAGf90_ArrayTemp_Character`
  `struct { Char *addr; Chrlen len; Offset extent[7];}`
  Describes a contiguous `CHARACTER` array; it is the same as the other array types with the addition of the `len` component for the `CHARACTER` length.
`__NAGf90_ArrayTemp_Derived`
  synonym for `ArrayTemp_Character`.
  Describes a contiguous array of any derived type. The `len` field in this case is the size of the derived type array element.

### 12.1.5 SUBROUTINE return types

#### 12.1.5.1 SUBROUTINEs with label arguments

The return type is `int`; its value is the index of the label to which control is to be transferred (1 for the first label, etc.). Zero or an out-of-range value indicates no control transfer is to take place.

#### 12.1.5.2 SUBROUTINEs with no label arguments

Return type is `void`.

### 12.1.6 FUNCTION return types

#### 12.1.6.1 Scalar

1. `INTEGER`, `LOGICAL` and `REAL`.
   The intrinsic type as listed above.
2. `COMPLEX`, -compatible option not used, and not Windows 64-bit mode.
   `Complex` or `DComplex` according to the precision.
3. `COMPLEX`, -compatible option used, or Windows 64-bit mode.
   Return type is `void`. The address of a temporary of type `Complex` or `DComplex` is passed as the initial argument of the function (the result is written to this location).
4. `CHARACTER` with fixed or assumed length.
   Return type is `void`. Two additional initial arguments are passed to the function, the first (`Char*`, `Char2*` or `Char4*`) being the address to which the result is to be written and the second (`Chrlen`) being the length of the result (in case the called function is of assumed length).
5. `CHARACTER` with variable length.
   Return type is `Substring`, `Substring2` or `Substring4` (described above). The called function allocates the storage for the string being returned; it is the caller's responsibility to deallocate it when it is no longer required.
6. Derived type.
   The derived-type struct.

#### 12.1.6.2 Scalar `POINTER` functions

Note that with all `POINTER`-valued functions the storage to which the result points may have been allocated within the called function or the result may point to pre-existing storage.

1. `INTEGER`, `LOGICAL`, `REAL` and `COMPLEX`.
   A pointer to the appropriate intrinsic type (e.g., `Complex*`).
2. `CHARACTER`
   Return type is `Substring`, `Substring2` or `Substring4`.
3. Derived type.
   A pointer to the derived-type struct.

#### 12.1.6.3 Array non-`POINTER` functions

1. Intrinsic types.
   The appropriate `__NAGf90_ArrayTemp_` struct for the intrinsic type, as described above.
2. Derived types.
   `__NAGf90_ArrayTemp_Derived` is returned with the `len` component set to the size of the derived-type struct.

#### 12.1.6.4 Array `POINTER` functions

1. `CLASS(*)`
   `__NAGf90_CSDope1`, `__NAGf90_CSDope2`… depending on the rank of the array.
2. `CLASS(`derived-type-name`)` `__NAGf90_NPDope1`, `__NAGf90_NPDope2`… depending on the rank of the array.
3. Non-polymorphic non-`CHARACTER` type.
   `__NAGf90_Dope1`, `__NAGf90_Dope2`… depending on the rank of the array.
4. `CHARACTER`.
   `__NAGf90_ChDope1`, `__NAGf90_ChDope2`… depending on the rank of the array.

Note that non-polymorphic derived-type arrays are returned as `__NAGf90_Dope`N structs.

### 12.1.7 Argument types

#### 12.1.7.1 `CHARACTER` type

All normal arguments of `CHARACTER` type, whether default `CHARACTER` or multi-byte `CHARACTER`, have an additional `Chrlen` argument being the length of the `CHARACTER` entity; this additional argument is passed at the end of the argument list after all the normal arguments. When there are several `CHARACTER` arguments their lengths are passed in order from left to right.

This is except on 32-bit Windows when the -compatible option is specified, the additional argument immediately follows the `CHARACTER` argument.

The other exception to this rule is for assumed-shape `CHARACTER` arrays; in this case the length of the dummy argument is taken directly from the field in the dope vector and is not passed separately.

#### 12.1.7.2 non-`POINTER` non-`ALLOCATABLE` Scalar

1. non-`CHARACTER` type.
   The address of the argument is passed (e.g., `Integer*` for an `INTEGER` argument).
2. `CHARACTER`.
   The address of the argument is passed, and additionally the length of the argument is passed as a separate `Chrlen` argument at the end of the argument list.

#### 12.1.7.3 `POINTER` and `ALLOCATABLE` Scalar

These are passed exactly the same as the normal case except that the address of the pointer (or allocatable descriptor) is passed (e.g., `Integer**` for an `INTEGER POINTER`).

#### 12.1.7.4 non-`POINTER` Array

1. Assumed shape.

   The address of an appropriate dope vector describing the array is passed (i.e., a `__NAGf90_CSDope`N`*`, `__NAGf90_NPDope`N`*`, `__NAGf90_Dope`N`*` or a `__NAGf90_ChDope`N`*`, depending on the polymorphism and type of the dummy argument). There is no need for the array to be contiguous as long as it can be described by an array section.

2. Other.
   The address of the first element of the array is passed. For `CHARACTER` arrays the length of each array element is passed as an `Chrlen` at the end of the argument list, the same as for scalars. The array must be contiguous.

#### 12.1.7.5 `POINTER` Array

The address of an appropriate dope vector is passed, the same as for assumed-shape arrays. For `CHARACTER` arrays the length is passed at the end as a separate argument.

#### 12.1.7.6 Procedures

The address of the procedure is passed. `CHARACTER` functions have the length passed as a separate argument at the end of the list; if the function is of variable length this length will be negative.

#### 12.1.7.7 `OPTIONAL` arguments

If an `OPTIONAL` argument is `.NOT.PRESENT()` a null pointer of the appropriate type is passed (e.g., for an `INTEGER` scalar, an `(Integer*)0` is passed).