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. 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.
Language | Array Declaration | Array Reference from Fortran |
---|---|---|
Fortran |
DIMENSION x(i, k) |
x(i, k) |
C/C++ |
type x[ k ] [ i ] |
x( i -1, k -1) |
The following information on Visual Basic and MASM applies to Windows systems only.
To pass an array from Visual Basic to Fortran, pass the first element of the array. By default, Visual Basic passes variables by reference, so passing the first element of the array will give Fortran the starting location of the array, just as Fortran expects. Visual Basic indexes the first array element as 0 by default, while Fortran by default indexes it as 1. Visual Basic indexing can be set to start with 1 using the statement:
Option Base 1
Alternatively, in the array declaration in either language you can set the array lower bound to any integer in the range -32,768 to 32,767. For example:
' In Basic
Declare Sub FORTARRAY Lib "fortarr.dll" (Barray as Single)
DIM barray (1 to 3, 1 to 7) As Single
Call FORTARRAY(barray (1,1))
! In Fortran
Subroutine FORTARRAY(arr)
REAL arr(1:3,1:7)
In MASM, arrays are one-dimensional and array elements must be referenced byte-by-byte. The assembler stores elements of the array consecutively in memory, with the first address referenced by the array name. You then access each element relative to the first, skipping the total number of bytes of the previous elements. For example:
xarray REAL4 1.1, 2.2, 3.3, 4.4 ; initializes ; a four element array with ; each element 4 bytes
Referencing xarray in MASM refers to the first element, the element containing 1.1. To refer to the second element, you must refer to the element 4 bytes beyond the first with xarray[4] or xarray+4. Similarly:
yarray BYTE 256 DUP ; establishes a ; 256 byte buffer, no initialization zarray SWORD 100 DUP(0) ; establishes 100 ; two-byte elements, initialized to 0
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:
Allocatable array
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), using an implicit interface allows 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 systems using IA-32 architecture are as follows:
The fourth longword (bytes 12 to 15) contains a set of flags used to store information about the array. This includes:
bit 1 (0x01): array is defined -- set if the array has been defined (storage allocated)
bit 2 (0x02): no deallocation allowed -- set if the array pointed to cannot be deallocated (that is, it is an explicit array target)
The remaining longwords (bytes 24 to 107) contain information about each dimension (up to seven). Each dimension is described by three additional longwords:
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:
The format for the descriptor on systems using Intel® 64 architecture and those using IA-64 architecture is identical to that on systems using IA-32 architecture, except that all fields are 8-bytes long, instead of 4-bytes.