配列と Fortran 配列記述子の処理

Fortran 95/90 では、配列を配列要素、配列サブセクション、または配列名で参照される配列全体として渡すことができます。Fortran では、配列要素は列優先順に編成されていて、最初の添字 (次元) から優先されます。

Fortran と他の言語の間で配列を使用する場合、要素のインデックスと順序を考慮する必要があります。配列要素は個別に参照し、追跡する必要があります。配列のインデックス付けは、ソースレベルでの問題であり、下位のデータに違いはありません。

Fortran および C の配列は、次の 2 つの点で異なります。

C では、X[3][3] として宣言されている配列の最初の 4 つの要素は次のとおりです。

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

一方、Fortran では、最初の 4 つの要素は次のとおりです。

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

インデックスの順序は、次元をいくつ宣言しても同じです。例えば、次のような C の宣言を考えてみます。

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

これは Fortran の次の宣言に相当します。

  INTEGER arr1( 20, 15, 10, 2 )

C の配列宣言に使用される定数は、他の言語のように上限ではなく、範囲を表しています。このため、int arr[5][5] と宣言された C 配列の最後の要素は、arr[5][5] ではなく arr[4][4] となります。

次の表に、対応する配列宣言を示します。

言語

配列宣言

Fortran からの配列参照

Fortran

DIMENSION x(i, k)

または

type x(i, k)

x(i, k)

C/C++

type x[ k ] [ i ]

x( i -1, k -1)

Visual Basic* および MASM での配列の処理

Visual Basic および MASM の情報は、Windows* システムのみが対象になります。

Visual Basic から Fortran に配列を渡すには、配列の最初の要素を渡します。デフォルトでは、Visual Basic は変数を参照によって渡すため、配列の最初の要素を渡すと、Fortran には Fortran が期待しているとおりに、配列の開始位置が与えられます。Visual Basic のデフォルトでは最初の配列要素のインデックスは 0 ですが、Fortran のデフォルトは 1 です。次の文を使用すると、Visual Basic のインデックス付けを 1 から開始させることができます。

  Option Base 1

別の方法として、いずれの言語でも、配列宣言中で、配列の下限を -32,768 ~ 32,767 の範囲の任意の整数に設定することができます。次に例を示します。

 ' 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)

MASM では、配列は 1 次元であり、配列要素はバイト単位に参照しなければなりません。アセンブラーにより、配列の要素はメモリー内に連続して格納され、最初のアドレスが配列名によって参照されます。個々の要素を参照するには、最初の要素を基準として、目的の要素の前にある要素の合計バイト数を読み飛ばします。次に例を示します。

 xarray    REAL4     1.1, 2.2, 3.3, 4.4 ; initializes
                      ; a four element array with
                      ; each element 4 bytes

MASM での xarray の参照は最初の要素、すなわち 1.1 を含む要素を参照します。第 2 の要素を参照するには、最初の要素の 4 バイト後にある要素を、xarray[4] または xarray+4 で参照する必要があります。次に別の例を示します。

 yarray     BYTE      256 DUP     ; establishes a
                ; 256 byte buffer, no initialization
 zarray SWORD 100 DUP(0) ; establishes 100
                ; two-byte elements, initialized to 0

インテル® Fortran の配列記述子の書式

Fortran 95/90 が複数のポインター・メモリー・アドレスを追跡しなければならない場合に備えて、インテル® Fortran コンパイラーは、配列の編成に関する詳細情報を格納する配列記述子 を使用します。

(結合またはプロシージャー・インターフェイス・ブロックによる) 明示的なインターフェイスを使用する場合、インテル® Fortran は次の形式の配列引数記述子を生成します。

一部のデータ構造体引数は、適切な明示的インターフェイスが提供されている場合でも、記述子を使用しません。例えば、明示的形状配列および形状引き継ぎ配列は記述子を使用しません。一方、配列ポインターおよび割付け配列は、引数として使用するかどうかにかかわらず、記述子を使用します。

インテル® Fortran と Fortran 以外の言語 (C など) の間で呼び出しを行う場合、暗黙的 インターフェイスを使用することで、インテル® Fortran の記述子なしで配列を渡すことができます。ただし、呼び出されたルーチンがインテル® Fortran 記述子に含まれる情報を必要とする場合、ルーチンを明示的 インターフェイスで宣言し、仮配列を形状引き継ぎ配列またはポインター属性として指定します。

Fortran 95/90 ポインターは、(配列境界が "矩形" である限り) 任意の形式で編成された任意のメモリー部分と関連付けることができます。また、Fortran 95/90 ポインターを C などの他の言語に渡し、その言語で記述子を正しく解釈して、必要な情報を取得することができます。

ただし、配列記述子を使用すると、エラーが起こる可能性が高くなります。また、対応するコードの移植性も損なわれます。特に、次のことに注意してください。

次に、IA-32 アーキテクチャーのシステム上における現在のインテル® Fortran の配列記述子のコンポーネントを示します。

次元数 1 の配列は、3 つのロングワードを追加する必要があるため、合計で 9 つのロングワード (6 + 3*1) が含まれ、バイト 35 で終わります。次元数 7 の配列は、合計で 27 のロングワード (6 + 3*7) が含まれ、バイト 107 で終わります。

例えば、次のような宣言の場合を考えてみます。

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

実引数 p の記述子には、次の値が含まれます。

Note icon

インテル® 64 および IA-64 アーキテクチャー・ベースのシステムの記述子は、IA-32 アーキテクチャー・ベースのシステムの記述子と同じ書式を使用しますが、すべてのフィールドが 4 バイトから 8 バイトになります。

大きな配列の処理

インテル® 64 アーキテクチャー・ベースの Linux* システムで、2GB を超える配列を使用するプログラムをコンパイルする場合、-mcmodel=medium または -mcmodel=large コンパイラー・オプションと -shared-intel オプションを指定する必要があります。詳細は、「インテル® 64 アーキテクチャー・ベースのシステムで使用するメモリーモデルの指定」を参照してください。