fortran66のブログ

fortran について書きます。

SUBROUTINE と FUNCTION は副作用の有無

SUBROUTINE と FUNCTION

FORTRAN の副プログラムは、3種に分かれます。1.SUBROUTINE、 2.FUNCTION、 3.BLOCK DATA です。このうち3番目の BLOCK DATA は、Fortran90 以降ではすでに役目を終えた機能なので、とりあえず無視できます。

では残り2種の SUBROUTINE と FUNCTION の使い分けは、どのようになっているのでしょうか? FORTRAN には、SUBROUTINE と FUNCTION の間に、最初期から明確な使い分けがあります。

SUBROUTINE および FUNCTION は、1958年に FORTRAN II で導入されましたが、すでにその時点で FUNCTION では仮引数の値を変えてはいけないこと(F90以降でいうところのINTENET(IN)属性であること、つまり引数変更の副作用が無いこと)を要求していました。これは FORTRAN コンパイラによる最適化で、例えば F = SIN(X) + SIN(X) のような数学関数の数式の F = 2.0 * SIN(X) への置き換えを許すためです。*1

Computer History Museum のサイトにある Reference Manual より http://www.computerhistory.org/collections/catalog/102653989

f:id:fortran66:20131116170229p:plain

基本的に Fortran では、副作用がある場合は SUBROUTINE を使うことになっています。したがって数学関数であってもエラーコードを返す場合は、FUNCTION ではなく SUBROUTINE が使われることになります。この使い分けは FORTRAN のライブラリを見るとよく分かると思います。

なお Fortran95 以降では、SUBROUTINE および FUNCTION 副プログラムに、副作用が無いことを保証する PURE 属性を明示的に指定できるようになりました。これによりコンパイラの文法チェックおよび最適化を助けることが可能になっています。

*1: FORTRAN IV 規格以降もこの制限があったのか、いつかの時点で許されたのか否か、まだよく調べていませんが、F77以降の実装では副作用のある FUNCTION が書けるのは普通だった気がします。ただ規格上での許可・禁止とは別に、道徳律上の禁止としては存在し続けていた気がします。