Handling Arrays and Fortran Array Descriptors

Fortran 95/90 allows arrays to be passed as array elements, as array subsections, or as whole arrays referenced by array name. Within Fortran, array elements are ordered in column-major order, meaning the subscripts of the lowest dimensions vary first.

When using arrays between Fortran and another language, differences in element indexing and ordering must be taken into account. You must reference the array elements individually and keep track of them. Fortran and C vary in the way that array elements are indexed. Array indexing is a source-level consideration and involves no difference in the underlying data.

Fortran and C arrays differ in two ways:

In C, the first four elements of an array declared as X[3][3] are:

  X[0][0] X[0][1] X[0][2] X[1][0]

In Fortran, the first four elements are:

  X(1,1) X(2,1) X(3,1) X(1,2)

The order of indexing extends to any number of dimensions you declare. For example, the C declaration:

int arr1[2][10][15][20];

is equivalent to the Fortran declaration:

INTEGER arr1( 20, 15, 10, 2 )

The constants used in a C array declaration represent extents, not upper bounds as they do in other languages. Therefore, the last element in the C array declared as int arr[5][5] is arr[4][4], not arr[5][5].

The following table shows equivalencies for array declarations.

Equivalent Array Declarations for Different Languages

Language

Array Declaration

Array Reference from Fortran

Fortran

DIMENSION x(i, k)
-or-
type
x(i, k)

x(i, k)

C/C++

type x[ k ] [ i ]

x( i -1, k -1)

Intel Fortran Array Descriptor Format

For cases where Fortran 95/90 needs to keep track of more than a pointer memory address, the Intel Fortran Compiler uses an array descriptor, which stores the details of how an array is organized.

When using an explicit interface (by association or procedure interface block), Intel Fortran generates a descriptor for the following types of array arguments:

Certain data structure arguments do not use a descriptor, even when an appropriate explicit interface is provided. For example, explicit-shape and assumed-size arrays do not use a descriptor. In contrast, array pointers and allocatable arrays use descriptors regardless of whether they are used as arguments.

When calling between Intel Fortran and a non-Fortran language (such as C), use an implicit interface to allow the array argument to be passed without an Intel Fortran descriptor. However, for cases where the called routine needs the information in the Intel Fortran descriptor, declare the routine with an explicit interface and specify the dummy array as either an assumed-shape array or with the pointer attribute.

You can associate a Fortran 95/90 pointer with any piece of memory, organized in any way desired (so long as it is "rectangular" in terms of array bounds). You can also pass Fortran 95/90 pointers to other languages, such as C, and have the other language correctly interpret the descriptor to obtain the information it needs.

However, using array descriptors can increase the opportunity for errors and the corresponding code is not portable. In particular, be aware of the following:

The components of the current Intel Fortran array descriptor on IA-32 systems are as follows:

An array of rank one requires three additional longwords for a total of nine longwords (6 + 3*1) and ends at byte 35. An array of rank seven is described in a total of 27 longwords (6 + 3*7) and ends at byte 107.

For example, consider the following declaration:

integer,target :: a(10,10) integer,pointer :: p(:,:) p => a(9:1:-2,1:9:3) call f(p) . . .

The descriptor for actual argument p would contain the following values:

Note

The format for the descriptor on Itanium-based systems is identical to that on IA-32 systems, except that all fields are 8-bytes long, instead of 4-bytes.