【Fortran学習|豆知識】プログラムを柔軟にする「手続き引数」の活用術:Fortranにおける関数注入の基礎

導入

数値計算プログラムを開発していると、「計算ロジック」と「計算対象の関数」を切り離したい場面に頻繁に遭遇します。例えば、汎用的な数値積分ルーチンを一度作成すれば、対象の関数を入れ替えるだけで様々な問題を解けるようになります。これを実現するのが「手続き引数(Dummy Procedures)」です。この手法を習得することで、コードの再利用性が飛躍的に向上し、メンテナンスが容易な設計が可能になります。

基礎知識

手続き引数とは、関数やサブルーチンの引数として、別の「関数やサブルーチンの名前」を渡す仕組みのことです。他の言語では「コールバック関数」や「関数ポインタ」と呼ばれる概念に相当します。Fortranなどの言語では、渡される手続きの形状(引数の型や数、戻り値の型)が一致しているかをコンパイル時に厳密に検証する仕組み(インターフェース)があり、これにより実行時の予期せぬエラーを未然に防ぐことができます。

実装/解決策

手続き引数を利用するには、以下の2ステップが必要です。
1. 受信側のサブルーチンで、受け取る手続きの形状を「interface」ブロックで定義する。
2. 呼び出し側で、対象となる関数名を実引数として渡す。
これにより、ソルバー側は「何が渡されるか」を事前に知ることができ、安全かつ汎用的な計算が可能となります。

サンプルプログラム

以下は、任意の関数を引数として受け取り、その値を表示する汎用的な計算処理の例です。

subroutine print_result(func, x)
! interfaceブロックで受け取る関数の仕様を定義
interface
function func(x) result(y)
real, intent(in) :: x
real :: y
end function func
end interface

real, intent(in) :: x
real :: result_val

! 関数を呼び出して計算
result_val = func(x)
print , “計算結果は: “, result_val
end subroutine

! 使用例:二乗を計算する関数
function square(x) result(y)
real, intent(in) :: x
real :: y
y = x x
end function

! メイン処理
program main
external square
! 関数名をそのまま引数として渡す
call print_result(square, 5.0)
end program

応用・注意点

現場での開発において注意すべき点は、「インターフェースの一致」です。渡される関数の引数の型や数が、interfaceブロックで定義したものと一箇所でも異なると、コンパイルエラーとなります。また、モジュールを使用している場合は、インターフェースをモジュール内に記述することで、コンパイラによる自動チェックがより強力に機能します。デバッグが困難なバグを避けるためにも、できるだけ「interface」を明示的に記述する習慣をつけましょう。

コメント

タイトルとURLをコピーしました