12.1 FortranとCの混合
Fortran ソースコードとCのコードを混在させる場合でFortran 2003のC相互運用を利用しない場合には、 以下の点に留意してください。
12.1.1 ネーミング規約
外部手続名、共通ブロック名、及び主プログラム名は小文字でアンダスコアを付加したものです(これは、手続き及び共通ブロックに対する標準UNIX f77と同じです)。 ‘main
’ 手続きはラッパーであり、環境を初期化し、実際の主プログラムを呼び出します。
モジュール変数とモジュール手続き名はモジュール名(小文字)に
‘_MP_
’を付加、さらに言語要素名(小文字)を付加する形で構成され
ます。
注:これらの規約は-compatible オプションを使用した場合には異なる可能性があります。 Windowsにおいてこのオプションを指定すると、 外部手続き名と共通ブロック名は大文字でかつアンダスコアが付かないものとなる一方、 モジュール要素はモジュール名を小文字ではなく大文字で持つことになります。 (64ビットシステムでは常に-compatibleです。) その他の多くの環境では、 このオプションの使用により名前にアンダースコアが既に含まれている場合に、 (通常付け加えられるもの後に更に)アンダースコアが追加されます。
12.1.2 初期化と終了
メインプログラムがFortranで書かれていない場合には初期化ルーチン__nAGf90_rts_init(int argc,char*argv[])または入出力初期化ルーチン
__nAGf90_io_init(void)のいずれかをCからコールする必要があります。
__nAGf90_rts_init
ルーチンはFortranの浮動小数点環境を初期化すると共に、
Fortran 2003の組込関数及びF90_UNIX
モジュールからのコマンド行引数に対するアクセスを可能にします。
またプログラムは__nAGf90_finish(int status)
によって終了させる必要がありま
すが、通常のC終了ルーチンを用いてすべてのFortranファイルのクローズ、Fortran
入出力バッファのフラッシュを行う前に、__nAGf90_io_finish(void)
をコールする
というアプローチも取れます。(フラッシュを行わないとオープンされている出力ファイルが壊れる可能性があります)
12.1.3 呼出し規約
以下のセクションでは、nAG Fortranコンパイラを用いてコンパイルされたFortran プログラムによって用いられる呼出し規約を、Cの用語を用いて詳細に記述します。 従ってこの情報はFortranとCのコードを混在させたいと考えている人にとって最も 有用と言えます。
近代FortranのFortran 77サブセットを対象とした規約はデファクトである
Unix f77規約と互換性があります(-f77 オプションを用いずに
コンパイルされたCOMPLEX
関数を除く)。
12.1.4 データタイプ
CからFortranへの交信に役立つデータタイプの定義は、通常/usr/local/lib/nAG_Fortran
(UNIX系のシステムの場合)に置かれているdope.h
とnagfortran.h
ファイルの中にあります。
Fortranデータタイプ | Fortran精度 | C typedef 名 |
INTEGER | 8 bits | Integer1 |
16 bits | Integer2 | |
32 bits | Integer または 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 ポインタ
スカラで多相でなく文字型でもないPOINTER
型は単にオブジェクトに対するCポインタです。
配列POINTER
型は対象の配列を記述するドープベクトル(dope vectors)です。
単なるアドレスとは異なり、これらのドープベクトルは連続な配列中における不連続
な部分配列を直接記述することができます。
詳細については、下記(__nAGf90_Dope
N および __nAGf90_ChDope
N)をご参照ください。
多相的ドープベクトルは __nAGf90_NPDope
N ですが、CLASS(*)
ポインタについては __nAGf90_CSDope
N です。
相互運用可能なドープベクトルは __nAGf90_CFI_Dope
N です。
12.1.4.2 構造型
Fortranの構造型はCのstruct
に翻訳されます。
BIND(C)
またはSEQUENCE
が使用された場合には、構造体内の項目の順序は
構造型定義中における順序と同一になります。
そうでない場合には、並び方を改善し記憶容量を減らすべく順序の入れ替えが行われ、
より大きな型が構造体の先頭の方に置かれることになります。順序の確認はCの出力コードを調べる事で行えます。
12.1.4.3 サポートタイプ
Char
unsigned char
基本(単一バイト)文字記憶のデータ型Char2
unsigned short
16ビット(JIS及びUCS-2)文字記憶のデータ型Char4
unsigned int
32ビット(UCS-4)文字記憶のデータ型Substring
struct { Char *addr; Chrlen len;}
単一バイト(基本)CHARACTER
列を記述します。 無指定文字長の基本CHARACTER
変数に使用され、 可変長のスカラ非POINTER
CHARACTER
関数、 及びすべてのPOINTER CHARACTER
関数の戻りタイプとして使用されます。Substring2
struct { Char2 *addr; Chrlen len;}
16ビット(JISもしくはUCS-2)CHARACTER
文字列を説明し、 無指定文字長の16ビットCHARACTER
変数、 及び可変長スカラ非POINTER
の16ビットCHARACTER
関数の戻り型、 及び全てのPOINTER
16ビットCHARACTER
関数で利用されます。Substring4
struct { Char4 *addr; Chrlen len;}
32ビット ISO_10646(USC-4)CHARACTER
文字列を説明し、 無指定文字長の32ビットCHARACTER
変数、 及び可変長スカラ非POINTER
のUSC-4CHARACTER
関数の戻り型、 及び全てのPOINTER
USC-4CHARACTER
関数で利用されます。Offset
int
,long
またはlong long
アドレス指定と添字計算のための整数型で、これは32ビットシステムおよび小規模モデル64ビットシステムではint
(32ビット)、大規模モデル64ビットシステムでは64ビット整数型です。Chrlen
- 通常は
int
、または64ビットWindows上ではlong long
。
文字長を表すための整数型。 Pointer
- 通常は
char *
。
任意の型を参照し、ポインタ算術に使用されるバイトポインタ。 Triplet
struct { Offset extent,mult,lower;}
配列次元のパラメータを含んでいます。extent
はその次元の大きさ、mult
はストライド(つまり、連続する要素間のバイト単位の距離)であり、lower
は下限です。これは__nAGf90_Dope
N および__nAGf90_ChDope
N 構造体の成分です。__nAGf90_Dope
Nstruct { Pointer addr; Offset offset; Triplet dim[N];}
多相的でない非CHARACTER
配列(構造型の配列を含む)のドープベクターです。N はランクで、1から7までです。addr
は最初の要素のアドレス、dim
は各次元を説明し、offset
は添字計算に加算するオフセット、つまりSUM(mult*lower)
です。これはPOINTER
配列関数の戻り値として使用され、仮定形状およびPOINTER
配列引数の引数型としてポインタが使用されます。ヌルに設定された配列ポインタは
addr
フィールドがヌルポインタですが、ゼロサイズの配列はaddr
フィールドがヌルポインタでないことに注意してください。__nAGf90_ChDope
Nstruct { Pointer addr; Chrlen len; Offset offset; Triplet dim[N];}
これらはDope
N 構造体と全く同じで、CHARACTER
長を指定するlen
コンポーネントが追加されています。__nAGf90_ArrayTemp_type
struct { type *addr; Offset extent[7];}
type の連続配列を記述し、これは次のいずれかです:Integer1
,Integer2
,Integer
,Integer4
,Logical1
,Logical2
,Logical
,Logical4
,Real
,Double
,QReal
,Complex
,DComplex
またはQComplex
。これはPOINTER
非配列関数の戻り値として使用されます。配列が記述するランク後のextent
値は未定義です。__nAGf90_ArrayTemp_Character
struct { Char *addr; Chrlen len; Offset extent[7];}
連続したCHARACTER
配列を記述します。これは他の配列タイプと同じで、CHARACTER
長を指定するlen
コンポーネントが追加されています。__nAGf90_ArrayTemp_Derived
ArrayTemp_Character
の同義語。
任意の構造型の連続配列を記述します。 この場合のlen
フィールドは構造型配列要素のサイズです。
12.1.5 SUBROUTINE戻りタイプ
12.1.5.1 ラベル引数を持つSUBROUTINE
戻りタイプはint
です。その値は制御を移す先のラベルに対するインデックス
(最初のラベルであれば1、以下同様)を表します。
ゼロ、または範囲外の値は制御の移行を伴わないことを示します。
12.1.5.2 ラベル引数を持たないSUBROUTINE
戻りタイプはvoid
です。
12.1.6 FUNCTION戻りタイプ
12.1.6.1
スカラ、非POINTER
関数
-
INTEGER
,LOGICAL
,REAL
上記組込み型。 -
COMPLEX
, -compatible オプション使用せず(もしくはWindows 64ビットモードではない)
精度に応じてComplex
、またはDComplex
。 -
COMPLEX
, -compatible オプション使用(もしくはWindows 64ビットモード)
戻りタイプはvoid
です。 型がComplex
またはDComplex
の一時データのアドレスが関数の初期引数 として渡されます(結果はその位置に書き込まれます)。 -
CHARACTER
, 固定長または長さ引継ぎ
戻りタイプはvoid
です。 2つの追加の初期引数が関数に引き渡されます。1番目のもの(Char*
,Char2*
,Char4*
のいずれか)は結果 を書き込む場所を示すアドレスを、2番目のもの(Chrlen
)は結果の長さ(呼 ばれた関数が長さ引継ぎ型の場合)を示します。 -
CHARACTER
, 可変長
戻りタイプはSubstring
,Substring2
,Substring4
(上記参照)のいずれかです。 呼ばれた関数は文字列用の記憶領域を割付けます。その領域が必要なくなったときに それを解放するのは呼出し元の責任です。 -
構造型
構造体。
12.1.6.2
スカラPOINTER
関数
すべてのPOINTER
値関数に関し、結果がポイントする記憶領域は呼ばれる関数
内で割付けられていることもあれば、結果が既存の記憶領域をポイントしていること
もある点に注意してください。
-
INTEGER
,LOGICAL
,REAL
,COMPLEX
適切な組込み型(例えばComplex*
)へのポインタ。 -
CHARACTER
戻りタイプはSubstring
,Substring2
,Substring4
のいずれかです。 -
構造型
構造体へのポインタ。
12.1.6.3
配列非POINTER
関数
-
組込み型。
上述のように、組込み型に適した__nAGf90_ArrayTemp_
構造体。 -
構造型。
__nAGf90_ArrayTemp_Derived
が返され、len
コンポーネントは構造型構造のサイズに設定されます。
12.1.6.4
配列POINTER
関数
-
CLASS(*)
__nAGf90_CSDope1
,__nAGf90_CSDope2...
配列の次元数に応じて。 -
CLASS(
構造型名)
__nAGf90_NPDope1
,__nAGf90_NPDope2...
配列の次元数に応じて。 -
多相的でない非
CHARACTER
型。
__nAGf90_Dope1
,__nAGf90_Dope2...
配列の次元数に応じて。 -
CHARACTER
。
__nAGf90_ChDope1
,__nAGf90_ChDope2...
配列の次元数に応じて。
多相的でない構造型配列は __nAGf90_Dope
N 構造体として返されます。
12.1.7 引数タイプ
12.1.7.1
CHARACTER
型
CHARACTER
型の通常の引数はすべて、CHARACTER
、マルチバイトCHARACTER
を問わず、
CHARACTER
言語要素の長さを示すChrlen
引数を伴っています。この追加引数はすべての通常の引数よりも後、
引数並びの末尾で引き渡されます。CHARACTER
引数が複数ある場合、その長さは左から右に順に引き渡されます。
これについて、32ビットのWindowsの場合で-compatibleオプションを指定した場合を除き、追加の引数はCHARACTER
の直後に続きます。
このルールに対するもう一つの例外は形状引継ぎCHARACTER
配列の場合ですが、この場合、仮引数の長さはドープベクトル中のフィールドから直接取得され、別個に引き渡されることはありません。
12.1.7.2
非POINTER
非ALLOCATABLE
スカラ
-
非
CHARACTER
型
引数のアドレスが引き渡されます(例:INTEGER
引数の場合のInteger*
)。 -
CHARACTER
引数のアドレスが引き渡されると共に、引数の長さが別のChrlen
引数として引数並びの末尾で引き渡されます。
12.1.7.3
POINTER
及びALLOCATABLE
スカラ
これらはポインタのアドレス(もしくは割付記述子)が引き渡される点を除くと、通常の場合と同様の形で引き渡されます(例:INTEGER POINTER
の場合のInteger**
)。
12.1.7.4
非POINTER
配列
-
形状引継ぎ配列
適切なドープベクトルを記述するアドレスが渡されます(つまり、
__nAGf90_CSDope
N*
,__nAGf90_NPDope
N*
,__nAGf90_Dope
N*
または__nAGf90_ChDope
N*
, 仮引数の多様性と型に応じて)。配列が連続でなくても、配列セクションによって記述できる限り問題ありません。 -
その他
配列の最初の要素のアドレスが引き渡されます。CHARACTER
配列の場合、それぞれの配列要素の長さはスカラに対する場合と 同様、引数並びの末尾でChrlen
として引き渡されます。 配列は連続でなくてはなりません。
12.1.7.5
POINTER
配列
引継ぎ形状配列の場合と同様、適切なドープベクトルのアドレスが引き渡されます。
CHARACTER
配列の場合、長さは別個の引数として末尾で引き渡されます。
12.1.7.6 手続き
手続きのアドレスが引き渡されます。CHARACTER
関数の場合、長さは別個の引数として並びの末尾で引き渡されます。
関数が可変長型の場合、この長さは負の値となります。
12.1.7.7
OPTIONAL
引数
OPTIONAL
な引数が.NOT.PRESENT()
である場合、適切な型のヌルポイン
タが引き渡されます(例えばINTEGER
スカラの場合、(Integer*)0
が
引き渡されます)。