2014-06-16

[Fortran] Optional引数がある外部サブルーチンを呼ぶにはinterfaceブロックが必要

FORTRAN77 までは、サブルーチンの呼び出しというのは、名前さえあっていれば
よかったのですが、
Optional引数のような非伝統的な機能(※)を使うときは、そのことを教えてや
らなければなりません。

※ Fortran 95 §12.3.1.1 参照。

* 呼び方(まあわかる)
* 引数キーワードを使って引用(使わなければいい)
* 総称名、利用者定義代入文、利用者定義演算子による引用
* 純粋手続きが必要な文脈での使用
(要は純粋手続き内部であって、それ自体が非伝統的)
* 呼ばれる物自体
* オプショナル引数がある
* 形状引継ぎ配列の引数(上下限のかわりにコロンを書いて、長さは呼び出し元
次第にする機能)がある
* ポインタの引数がある
* TARGET属性を持った引数がある
* (関数が)配列値の結果を返す
* (関数が)ポインタの結果を返す
* (文字型関数が)返す結果の文字長パラメタ値が定数でも引継ぎでもない

呼ばれる側に由来する制約は、呼ぶ側では必ずしも承知していないので、落とし
穴となりえます。

モジュール、他のサブルーチンまたは関数、あるいは主プログラムの中に入って
いるサブルーチンは、
どこかしらに「非伝統的な機能を使っているよ」ということを伝えることができ
ます。
しかし、外部サブルーチン(ソースファイルの先頭が subroutine 文になってい
るもの)を呼び出すときは、
コンパイラは誰にもそのことを教えてもらうことができません。

呼ばれる方のサブルーチンをモジュールに入れるように変えて、モジュールを
use するのが綺麗ですが、
名前を考えたり、 .mod ファイルが生じたり、面倒です。
てっとりばやい救済は、呼び側で interface ブロックを使うことです。

subroutine super
INTERFACE
subroutine sub(a, b, c)
integer, intent(inout):: a, b
integer, intent(in), OPTIONAL:: c
end subroutine
END INTERFACE
call sub(1, 2)
end subroutine

subroutine sub(a, b, c)
integer, intent(inout):: a, b
integer, intent(in), OPTIONAL:: c
end subroutine

0 件のコメント:

コメントを投稿