この章では、Fortran と C の相互運用性に関する問題を取り上げます。ここで説明する内容は、Sun Studio Fortran 95 と C コンパイラの仕様のみに該当します。
「11.9 Fortran 2003 と C の相互運用性」では、Fortran 2003 規格草案の第 15 節で提案されている C とのリンク機能について簡単に説明します。この規格草案は、Web サイト http://www.j3-fortran.org で入手できます。95 コンパイラは、規格に記述されているとおりに、これらの機能を実装しています。
特に注記がある場合を除き、32 ビット x86 プロセッサは 32 ビット SPARC プロセッサと同様に取り扱います。64 ビット x86 と 64 ビット SPARC も同じです。ただし例外として、REAL*16 および COMPLEX*32 データ型は x86 システム用に定義されておらず、SPARC のみで利用可能です。
ほとんどの C と Fortran のインタフェースでは、次に示すことを正しく理解しておく必要があります。
関数とサブルーチンの定義と呼び出し
データ型の互換性
引数の参照渡しと値渡し
引数の順番
手続き名 - 大文字、小文字、または末尾に下線 (_) 付き
正しいライブラリ参照をリンカーに渡す
また、一部の C と Fortran のインタフェースでは、次に示すことを正しく理解しておく必要があります。
配列の添字付けと順序
ファイル記述子と stdio
ファイルのアクセス権
「関数」という言葉の意味は、C と Fortran では異なります。 状況によって、どちらの意味で解釈するかが重要です。
Fortran では、関数とは値を返すものであり、値を返さないものはサブルーチンといいます。
Fortran ルーチンから C 関数を呼び出す場合
値を返す C の関数は、Fortran から関数として呼び出します。
値を返さない C の関数は、Fortran からサブルーチンとして呼び出します。
C 関数から Fortran 副プログラムを呼び出す場合
Fortran 副プログラムが関数の場合は、C から、対応するデータ型を返す関数として呼び出します。
Fortran 副プログラムがサブルーチンの場合は、C から int (これは Fortran の INTEGER*4 に対応する) または void を返す関数として呼び出します。Fortran のサブルーチンが選択戻りをする場合は 1 つの値が戻されます。Fortran のサブルーチンが選択戻りをする場合は 1 つの値が戻されます。 この場合、RETURN 文にある式の値です。RETURN 文に式がない場合、または SUBROUTINE 文で選択戻りが 宣言されている場合、ゼロが戻されます。
表 11–2 では、Fortran 95 のデータ型と C のデータ型のデータサイズとデフォルトの境界整列を比較しています。ここでは、境界に影響したり、適用されるデフォルトのデータサイズを昇格させたりするコンパイルオプションを指定しないものとします。次の点に注意してください。
C のデータ型 int、long int、long は、32 ビット環境では等価です (4 バイト)。しかし、64 ビット環境では long とポインタは 8 バイトになります。これは LP64 データモデルと呼ばれます。
64 ビット環境で -m64 および、これに相当するオプションを使用してコンパイルすると、REAL*16 と COMPLEX*32 は 16 バイト境界に整列されます。
4/8 と示されている境界整列は、デフォルトでは 8 バイト境界を意味しますが、共通ブロックでは 4 バイト境界を意味しています。共通ブロックでのデフォルトの最大境界整列は 4 バイトです。4/8/16 は、-m64 オプションを使用してコンパイルしたとき 16 バイト境界に整列されることを意味します。
REAL(KIND=16)、REAL*16、COMPLEX(KIND=16)、および COMPLEX*32 は SPARC プラットフォームでのみ使用できます。
配列と構造体の要素および欄はそれぞれ互換性がなければいけません。
配列、文字列、構造体を値で渡すことはできません。
呼び出し側で %VAL(arg) を使用すると、Fortran 95 ルーチンから C ルーチンに値で引数を渡すことができます。C から Fortran 95 に値で引数を渡すことはできますが、Fortran ルーチンに、VALUE 属性とともに仮引数を宣言している明示的なインタフェースブロックがあることが条件となります。
数値シーケンス型の要素は共通ブロックと同様に整列され、-aligncommon オプションによっても制御されます。 数値シーケンス型は、すべての要素がデフォルトの整数型かデフォルトの実数型、倍精度実数型、デフォルトの複素数型、デフォルトの論理型のいずれかで、ポインタではない連続型です。
QUAD 変数を除き、数値シーケンス型ではないデータ型の要素は、たいていの場合、自然整列になります。4 倍精度の変数の場合、境界整列は 32 ビットと 64 ビットの SPARC プラットフォームで異なります。
VAX 構造体の要素、および BIND(C) 属性で定義されたデータ型は、どのプラットフォームでも C の構造体と同じ境界整列になります。
Fortran 95 のデータ型 |
C のデータ型 |
サイズ |
境界 |
|
---|---|---|---|---|
BYTE x |
char x |
1 |
1 |
|
CHARACTER x |
unsigned char x ; |
1 |
1 |
|
CHARACTER (LEN=n) x |
unsigned char x[n] ; |
n |
1 |
|
COMPLEX x |
struct {float r,i;} x; |
8 |
4 |
|
COMPLEX (KIND=4) x COMPLEX (KIND=8) x COMPLEX (KIND=16) x (SPARC) |
struct {float r,i;} x; struct {double dr,di;} x; struct {long double, dr,di;} x; |
8 16 32 |
4 4/8 4/8/16 |
|
DOUBLE COMPLEX x |
struct {double dr, di;} x; |
16 |
4/8 |
|
DOUBLE PRECISION x |
double x ; |
8 |
4 |
|
REAL x |
float x ; |
4 |
4 |
|
REAL (KIND=4) x REAL (KIND=8) x REAL (KIND=16) x (SPARC) |
float x ; double x ; long double x ; |
4 8 16 |
4 4/8 4/8/16 |
|
INTEGER x |
int x ; |
4 |
4 |
|
INTEGER (KIND=1) x INTEGER (KIND=2) x INTEGER (KIND=4) x INTEGER (KIND=8) x |
signed char x ; short x ; int x ; long long int x; |
1 2 4 8 |
4 4 4 4 |
|
LOGICAL x |
int x ; |
4 |
4 |
|
LOGICAL (KIND=1) x LOGICAL (KIND=2) x LOGICAL (KIND=4) x LOGICAL (KIND=8) x |
signed char x ; short x ; int x ; long long int x; |
1 2 4 8 |
4 4 4 4 |
C と Fortran では、字種 (大文字/小文字) に関する扱いが異なります。
C では字種に意味があり、大文字と小文字を別のものとして扱います。
Fortran では、デフォルトでは字種に意味がありません。
f95 のデフォルトでは、副プログラム名を小文字に変換して、字種を無視します。 つまり、文字列定数の中を除き、すべての大文字を小文字に変換します。
大文字と小文字に関する問題には、一般に次のような 2 つの解決策があります。
C の副プログラムで、C の関数名をすべて小文字にします。
-U オプションを付けて Fortran プログラムをコンパイルします。 これは、コンパイラに、関数名と副プログラム名における既存の字種の区別をそのまま保持させるオプションです。
前述の 2 つの解決策のどちらか 1 つを使用してください。 両方を使用してはいけません。
この章の例のほとんどは、C の関数名に小文字だけを使用しています。f95-U コンパイラオプションは使用していません。
Fortran コンパイラは、通常、入口定義と呼び出しの両方に現れる副プログラムの名前に下線 (_) を追加します。これによって、ユーザー割り当て名が同じである C の手続きや外部変数と区別します。Fortran ライブラリのほとんどすべての手続き名には、ユーザーが割り当てるサブルーチンとの競合を減らすため、先頭に 2 つの下線が付けられています。
下線に関する問題には、一般に次の 3 つの解決策があります。
C の関数で、下線を追加して関数名を変更する。
f95 の -ext_names オプションを使用して、下線を使用しないで外部名への参照をコンパイルする。
これらの中のいずれか 1 つを使用してください。
この章の例は、BIND(C) 属性宣言を使用して、下線をなくしています。 BIND(C) は、C の外部関数が Fortran から呼び出し可能なこと、また Fortran ルーチンが引数として C から呼び出し可能なことを宣言します。Fortran は、通常、外部名に対して行うようには下線を付加しません。 BIND(C) は、そうした参照を含むそれぞれの副プログラム内で使用する必要があります。使用規則は次のとおりです。
FUNCTION ABC EXTERNAL XYZ BIND(C) ABC, XYZ |
この例では、XYZ が外部 C 関数であることばかりでなく、Fortran の呼び出し側の ABC を C 関数から呼び出し可能であると宣言しています。BIND(C) を使用すると、C の関数の方で名前に下線を追加する必要はありません。
一般的には、Fortran ルーチンは引数を参照で渡します。呼び出し時に、非標準関数の %VAL() に引数を入れると、呼び出し元のルーチンはその引数を値で渡します。
Fortran 95 で引数を値で渡す場合の標準的な方法は、VALUE 属性と INTERFACE ブロックを使用する方法です。「11.4 データ引数の値渡し」を参照してください。
一般的には、C は引数を値で渡します。引数の前にアンパサンド記号 (&) を付けた場合は、C はその引数を、ポインタを使用して参照で渡します。配列と文字列に関しては、C でも常に参照で渡します。
文字列の引数の場合を除くと、Fortran と C は引数を同じ順序で渡します。ただし、各文字列引数については、Fortran ではさらに文字列の長さを示す引数も渡します。文字列長は、値で渡される C の long int の量と同じです。
引数の順序は次のとおりです。
各引数 (データであっても関数であっても) のアドレス
各文字引数に対する long int (文字列長の並び全体は、ほかの引数の並び全体のあとにきます)
例:
Fortran コードの一部 |
対応する C のコード |
||
---|---|---|---|
|
|
配列の添字付けと順番については Fortran と C とでは異なります。
C の配列は常にゼロから始まりますが、Fortran の配列はデフォルトでは 1 から始まります。この問題には、次のような 2 つの解決策があります。
前述の例のように、Fortran のデフォルトを使用します。このときは、Fortran の B(2) 要素は C の b[1] 要素と同義になります。
Fortran の配列 B を B(0) で始まるように指定します。
INTEGER B(0:2) |
このときは、Fortran の要素 B(1) が C の b[1] 要素と同義になります。
Fortran の配列は列主導の順番で、A(3,2) のように格納されます。
A(1,1) A(2,1) A(3,1) A(1,2) A(2,2) A(3,2) |
C の配列は行主導の順番で、A[3][2] のように格納されます。
A[0][0] A[0][1] A[1][0] A[1][1] A[2][0] A[2][1] |
1 次元の配列では、これによって問題は生じません。しかし、多次元の配列では、すべての参照と宣言における添字の順番と使用法に気をつけてください。 なんらかの調整が必要になります。
たとえば、行列操作の一部を C で行い、残りを Fortran で行うのは混乱が生じる可能性があります。一方の言語で全体の配列をルーチンに渡し、そのルーチン内ですべての行列操作を実行すれば、混乱を避けることができます。
Fortran の入出力チャネルは、装置番号で表されます。プラットフォームとして使用している SunOS オペレーティングシステムは、装置番号ではなく、ファイル記述子を扱います。Fortran の実行時のシステムが装置番号からファイル記述子に変換するので、ほとんどの Fortran プログラムはファイル記述子を認識する必要はありません。
C プログラムの多くは、標準入出力 (stdio) と呼ばれるサブルーチンセットを使用しています。Fortran の入出力関数の多くは標準入出力を使用しており、これはオペレーティングシステムの入出力呼び出しを使用しています。このような入出力システムの特性の一部を次の表に示します。
表 11–2 Fortran と C の入出力の比較
|
Fortran 装置 |
標準入出力のファイルポインタ |
ファイル記述子 |
---|---|---|---|
ファイルを開く |
読み書き用に開く |
読み取り用、書き込み用、読み書き両用、または追加用に開く。open(2) 参照 |
読み取り用、書き込み用、または読み書き両用に開く。 |
属性 |
書式付き、書式なし |
常に書式なし、ただし、書式解釈ルーチンによる読み書きは可能。 |
常に書式なし |
探査 |
直接、順番 |
物理ファイルの表現が直接探査の場合は直接探査、ただし、常に順番に読み取り可。 |
物理ファイルの表現が直接探査の場合は直接探査、ただし、常に順番に読み取り可。 |
構造 |
レコード |
バイトストリーム |
バイトストリーム |
形式 |
任意の負でない 0 から 2147483647 までの整数 |
ユーザーのアドレス空間における構造体へのポインタ |
0 から 1023 までの整数 |
適切な Fortran および C ライブラリをリンクするためには、f95 コマンドを使用して、リンカーを起動します。
例 1: コンパイラを使用してリンクします。
demo% cc -c someCroutine.c demo% f95 theF95routine.f someCroutine.o <- このコマンド行でリンクを実行 demo% a.out 4.0 4.5 8.0 9.0 demo% |
f95 によりコンパイルされた主プログラムでは、プログラム起動時にライブラリのダミー初期化ルーチン f90_init を呼び出します。ライブラリのルーチンは、ダミーであり、何も処理しません。コンパイラにより生成される呼び出しでは、プログラムの引数と環境へのポインタが渡されます。これらの呼び出しにより、各自の C 言語ルーチンでプログラムの起動前に独自の方法でプログラムを初期化するときに使用できるソフトウェアのフックが提供されます。
このような初期化ルーチンの使用法の一つに、国際化された Fortran プログラムに対して setlocale を呼び出す方法があります。setlocale は、libc が静的にリンクされている場合機能しないので、libc に動的にリンクされる Fortran プログラムだけが国際化できます。
ライブラリの init ルーチンのソースコードは、次のとおりです。
void f90_init(int *argc_ptr, char ***argv_ptr, Char ***envp_ptr) {} |
f90_init は、f95 主プログラムにより呼び出されます。各引数には、argc のアドレス、argv のアドレス、envp のアドレスが設定されます。
Fortran ルーチンと C 手続きとの間でデータを渡す標準的な方法は、参照渡しです。C の手続きから見ると、Fortran の副プログラムまたは関数呼び出しは、すべての引数をポインタで表す手続き呼び出しのようになります。唯一異なる点は、Fortran が文字列と関数を引数として扱う方法と、CHARACTER*n 関数の戻り値として扱う方法です。
単純なデータ型の場合 (COMPLEX または CHARACTER 文字列以外)、次に示すように、C ルーチンにおいてそれぞれ関連する引数をポインタにより定義するか、または渡します。
表 11–3 単純型データを渡す
Fortran が C を呼び出す |
C が Fortran を呼び出す |
||
---|---|---|---|
|
|
Fortran の複素数データ項については、2 つの float または 2 つの double からなる 1 つの C の構造体へのポインタとして渡します。
表 11–4 複素数データを渡す
Fortran が C を呼び出す |
C が Fortran を呼び出す |
||
---|---|---|---|
|
|
64 ビット環境では、COMPLEX 値がレジスタに戻されま す。
C と Fortran ルーチンとの間で文字列を渡すことは推奨できません。 これは、標準的なインタフェースがないからです。ただし、次を考慮してください。
すべての C 文字列は参照で渡される。
Fortran の呼び出しは、引数リストにある character 型のすべての引数についてそれぞれもう 1 つの引数を渡します。この追加引数は、文字列の長さを渡すもので、値で渡される C の long int と同じです。ただし、これは実装方式に依存します。この文字列の長さを渡す追加引数は、呼び出しの明示的に指定した引数のあとに現れます。
次の例で、文字列を引数とする Fortran 呼び出しを、対応する C のコードとともに示します。
表 11–5 CHARACTER 文字列を渡す
Fortran が C を呼び出す |
C に対応する Fortran のコード |
||
---|---|---|---|
|
|
文字列の長さが呼び出されたルーチンで必要なければ、追加の引数は無視されます。ただし、Fortran では C のように明示的なヌル文字で文字列を自動的に終了させません。これは、呼び出し側のプログラムで追加する必要があります。
文字配列への呼び出しは、単一文字変数への呼び出しと似ています。配列の開始アドレスが渡され、それが使用する長さが配列の単一要素の長さになります。
C では配列の添字が 0 で始まります。
表 11–6 1 次元配列を渡す
Fortran が C を呼び出す |
C が Fortran を呼び出す |
||
---|---|---|---|
|
|
C と Fortran とでは行と列が入れ替わります。
表 11–7 2 次元配列を渡す
Fortran が C を呼び出す |
C が Fortran を呼び出す |
||
---|---|---|---|
|
|
C と Fortran 95 の構造型は、対応する成分間に互換性があれば、それぞれのルーチン間で相互に受け渡しできます。f95 は、古い STRUCTURE 文を受け付けます。
表 11–8 古い FORTRAN 77 の STRUCTURE レコードを渡す
Fortran が C を呼び出す |
C が Fortran を呼び出す |
||
---|---|---|---|
|
|
Fortran (VAX) 77 構造体は、どのプラットフォームでもつねに C の構造体と同じ境界整列になります。ただし、この境界整列はプラットフォーム間で異なります。
表 11–9 Fortran 95 構造体を渡す
Fortran 95 が C を呼び出す |
C が Fortran 95 を呼び出す |
||
---|---|---|---|
|
|
Fortran 95 規格では、記憶領域の並び順がコンパイルによって保持されるように、構造型の定義に SEQUENCE 文を含めなければならないことになっています。
どのプラットフォームでも、デフォルトでは、数値シーケンス型の要素はワード (4 バイト) 境界に整列されます。これは、x86 プラットフォームでも C の構造体の境界整列と同じですが、SPARC V8 および V9 プラットフォームでの C 境界整列と異なります。数値シーケンス型の境界整列を C の構造体の整列に一致させるには、-aligncommon オプションを使用します。32 ビットの SPARC の C 構造体と一致させるには -aligncommon=8、64 ビットの SPARC の C 構造体と一致させるには -aligncommon=16 を使用してください。
SEQUENCE を使って明示的に宣言されていない構造型は、SPARC V8 および V9 プラットフォームでは C の構造体と同じ境界整列になりますが、x86 プラットフォームでは異なります。コンパイラオプションを使って、この整列を変更することはできません。
FORTRAN 77 (Cray) のポインタは、ポインタへのポインタとして C ルーチンに渡すことができます。 これは、Fortran ルーチンが引数を参照で渡すからです。
表 11–10 FORTRAN 77 (Cray) の POINTER を渡す
Fortran が C を呼び出す |
C が Fortran を呼び出す |
||
---|---|---|---|
|
|
C ポインタは Fortran 95 のスカラーポインタとは互換性がありますが、配列ポインタとは互換性がありません。
Fortran 95 がスカラーポインタで C を呼び出す |
||
---|---|---|
Fortran 95 ルーチン:
C ルーチン
|
Cray ポインタと Fortran 95 ポインタの主な違いは、Cray ポインタには常にターゲットが指定されることです。多くの場合、Fortran 95 ポインタを宣言すると、ターゲットは自動的に特定されます。また、呼び出された側の C ルーチンにも明示的な INTERFACE ブロックが必要です。
配列または部分配列への Fortran 95 ポインタを渡すには、次の例のように特定の INTERFACE ブロックが必要です。
Fortran 95 ルーチン INTERFACE SUBROUTINE S(P) integer P(*) END SUBROUTINE S END INTERFACE integer, target:: A(0:9) integer, pointer :: P(:) P => A(0:9:2) !! ポインタは A の要素を 1 つおきに選択 call S(P) ... C ルーチン void s_(int p[]) { /* 中央の要素を変更する */ p[2] = 444; } |
C ルーチン S は Fortran 95 ルーチンでありません。このため、INTERFACE ブロックでは、想定された形 (integer P(:)) でルーチン S を定義することはできません。C ルーチンが配列の実際のサイズを知る必要がある場合は、配列を引数として C ルーチンに渡す必要があります。
C と Fortran では添字付けの方法が異なり、C 配列の添字は 0 から始まることに注意してください。
Fortran 95 のプログラムでは、C から呼び出されるときに仮引数の VALUE 属性を使用し、Fortran 95 から呼び出す C ルーチンのために INTERFACE ブロックを追加する必要があります。
表 11–11 C と Fortran 95 の間で単純なデータ要素を渡す
Fortran 95 が C を呼び出す |
C が Fortran 95 を呼び出す |
||
---|---|---|---|
|
|
C ルーチンを実引数として別のデータ型で呼び出す場合は、INTERFACE ブロックに !$PRAGMA IGNORE_TKR I を含めることによって、実引数と仮引数の型、種類、ランクの一致をコンパイラから要求されないようにします。
古い FORTRAN 77 での値による呼び出しは、単純型のデータでだけ、FORTRAN 77 ルーチンが C のルーチンを呼び出す場合にかぎり使用できました。C のルーチンから FORTRAN 77 ルーチンを呼び出して、値で引数を渡す方法はありません。配列、文字列、構造体は、参照で渡すようにしてください。
FORTRAN 77 ルーチンから C ルーチンに値を渡すには、非標準の Fortran 関数 %VAL(arg) を呼び出しの中で引数として使用してください。
次の例では、FORTRAN 77 ルーチンが値により x を渡し、参照により y を渡しています。C のルーチンは x と y を増分しましたが、y だけが変更されます。
Fortran が C を呼び出す |
|||
---|---|---|---|
Fortran ルーチン:
C ルーチン
コンパイルと実行による出力:
|
BYTE、INTEGER、REAL、LOGICAL、DOUBLE PRECISION、または REAL*16 型の値を戻す Fortran 関数は、互換性のある型を戻す C の関数と等価です (表 11–1 を参照)。文字関数の戻り値には引数が 2 つ追加され、複素数関数の戻り値には引数が 1 つ追加されます。
次の例は REAL または float 値を戻します。BYTE、INTEGER、LOGICAL、DOUBLE PRECISION、および REAL*16 も同じような方法で扱われます。
表 11–12 REAL または float の値を戻す関数
Fortran が C を呼び出す |
C が Fortran を呼び出す |
||
---|---|---|---|
|
|
複素数データの相互運用性に関する状況は、32 ビットの実装と 64 ビットの SPARC V9 の実装では異なります。
32 ビットプラットフォームで、COMPLEX または DOUBLE COMPLEX を戻す Fortran 関数は、メモリーにある戻り値を指す追加の引数を最初の引数として持つ C の関数と同じです。Fortran 関数と対応する C 関数の一般的な形式は次のとおりです。
Fortran 関数 |
C 関数 |
||
---|---|---|---|
|
|
表 11–13 複素数データを戻す関数 (32 ビット SPARC)
Fortran が C を呼び出す |
C が Fortran を呼び出す |
||
---|---|---|---|
|
|
64 ビット SPARC 環境では、COMPLEX 値が浮動小数点レジスタに戻されます。COMPLEX と DOUBLE COMPLEX はそれぞれ %f0 と %f1 に戻され、COMPLEX*32 は %f0、%f1、%f2、および %f3 に戻されます。64 ビット SPARC では、要素がすべて浮動小数点型の構造体を返す C 関数は、浮動小数点レジスタで構造体を返します。ただし、そのために必要なレジスタの数が 4 個以下の場合にかぎられます。Fortran 関数と対応する C 関数の一般的な形式は次のとおりです。
Fortran 関数 |
C 関数 |
---|---|
COMPLEX FUNCTION CF(a1, a2, ..., an) |
struct {float r,i;} cf_ (a1, a2, ..., an) |
表 11–14 複素数データを戻す関数 (64 ビット SPARC)
Fortran が C を呼び出す |
|
---|---|
|
|
C が Fortran を呼び出す |
|
|
C と Fortran ルーチンの間で文字列を渡すことは推奨できません。ただし、Fortran の文字列の値を持つ関数は、データアドレスとデータ長の 2 つの引数がはじめに追加された C の関数と同じです。Fortran 関数と対応する C 関数の一般的な形式は次のとおりです。
Fortran 関数 |
C 関数 |
|
---|---|---|
CHARACTER*n FUNCTION C(a1, ..., an) |
|
次に例を示します。
表 11–15 CHARACTER 文字列を戻す関数
Fortran が C を呼び出す |
C が Fortran を呼び出す |
||
---|---|---|---|
|
|
この例では、C 関数と呼び出し側の C ルーチンは、リストの最初に 2 つの引数 (結果として戻される文字列へのポインタと文字列長) が、そして、リストの最後に 1 つの追加引数 (文字列引数の長さ) が追加されています。C から呼び出された Fortran ルーチンでは最後のヌル文字を明示的に追加する必要があることに注意してください。Fortran の文字列は、デフォルトでは NULL 終端されません。
Fortran の名前付き COMMON は、大域的構造体を使用して C の中で代替できます。
表 11–16 Fortran の名前付き COMMON 定義
Fortran の COMMON 定義 |
C "COMMON" 定義 |
||
---|---|---|---|
|
|
C ルーチンにより確立された外部名は、Fortran プログラムにより作成されたブロックとリンクさせるために下線で終了しなければいけません。C 指令 #pragma pack は Fortran のときと同じ埋め込みが必要な場合があります。
f95 は、デフォルトで、共通ブロックのデータを最大で 4 バイトの境界に配列します。共通ブロック内のすべてのデータ要素の自然配列取得し、デフォルトの構造配列と一致させるには、Fortran ルーチンをコンパイルする際にオプション -aligncommon=16 を使用します。
Fortran の入出力とC の入出力を混合すること (C ルーチンと Fortran ルーチンの両方から入出力呼び出しを発行すること) は推奨できません。すべて Fortran の入出力で行うか、すべて C の入出力で行うかのどちらかに統一するのが安全です。
Fortran の入出力ライブラリは、大部分が C の標準入出力ライブラリに追加する形で実装されています。Fortran プログラムで開いた装置はすべて、標準入出力のファイル構造と対応付けられています。stdin、stdout、stderr のストリームに関しては、ファイル構造を明示的に参照する必要がなく、共有できます。
Fortran の主プログラムが入出力を行うために C を呼び出す場合は、プログラム起動時に Fortran の入出力ライブラリを初期化して、装置 0、5、6 をそれぞれ stderr、stdin、stdout に接続します。ファイル記述子を開いて入出力を実行する場合、C の関数は Fortran の入出力環境を考慮する必要があります。
たとえ主プログラムが C で書かれていても、f95 でリンクするようにしてください。
FORTRAN 77 の選択戻り機能はすでに廃止されているので、移植上の問題がなければ使用しないでください。選択戻りに対応する機能は C にはありません。 したがって、問題は C のルーチンが選択戻りを持つ Fortran のルーチンを呼び出す場合だけです。Fortran 95 は FORTRAN 77 の選択戻りを受け付けますが、これを利用することはお勧めしません。
選択戻りは、RETURN 文の式の int 値を戻します。これは実装方式にかなり依存するため、使用しないでください。
表 11–17 選択戻り (あまり使用されません)
C が Fortran を呼び出す |
例の実行 |
||
---|---|---|---|
|
C ルーチンは Fortran ルーチンから戻り値 2 を受け取る。これは、RETURN 2 文が実行されたためである。 |
Fortran 2003 規格の草案 (http://www.j3-fortran.org から入手可能) では、C プログラミング言語で定義された手続きおよび大域的変数を Fortran 95 プログラム内から参照する方法について規定しています。また逆に、C 手続きから参照できるように Fortran 副プログラムや大域的変数を定義する方法も規定しています。
設計上は、Fortran 95 プログラムと C プログラムの相互運用性を実現するこれらの機能を使用すると、規格を満たすプラットフォーム間での移植可能性が保証されます。
Fortran 2000 では、構造型用の BIND 属性と、ISO_C_BINDING 組み込みモジュールを提供しています。このモジュールを使用すると、Fortran プログラムから、相互運用可能なオブジェクトの仕様をサポートしている特定の名前付き定数、構造型、および手続きにアクセスできます。詳細は、Fortran 2003 規格を参照してください。