昔のFORTRANでは、EQUIVALNECE や COMMON で変数の番地を共有させたり、副プログラムの呼び出しでわざと型の違う変数を渡したり、文字型がなかったので適当な型の変数の中にホレリスで文字データをいれたりして、必要とあらば型を無視して自由にやれたのですが、時代が進んで Fortran90 では型や配列の次元(rank)にうるさくなって、昔より窮屈になりました。
ただチェックなどが厳しくなってからは、明らかに実行時エラーなどが減ったので、型や次元のチェックが有効だったのは間違いありません。とはいえ窮屈すぎると型や次元ごとに内容の重複するサブルーチンなどを用意する必要があるので、別の面倒が増えてきました。
その結果 Fortran95 では 要素型(elemental)サブルーチンが定義できるようになり、次元に関する制約が緩められ、Fortran2003 では動的プログラミング的な要素が導入されて、型チェックが緩くなることになりました。
ここでは Fortran2003 で導入された万能型 class() について書いておきます。class () 型の変数には、どんな型の値も代入できるのですが、使い方が面倒なので備忘録的として。
class (*) の制約
class (*) 型の変数は、必ず allocatable 属性か pointer 属性を持たねばなりません。直接の代入や書き出しもできません。代入は allocate で、出力等の処理は select type ... end select 構文を用います。
program test implicit none class (*), allocatable :: a, b, c, d allocate(a, source = 1 ) allocate(b, source = 1.0 ) allocate(c, source = 1.0d0) allocate(d, source = 'one') call prn(a) call prn(b) call prn(c) call prn(d) stop contains subroutine prn(c) class (*), intent(in) :: c select type (c) type is (integer) print *, c type is ( real(kind(0.0e0)) ) print *, c type is ( real(kind(0.0d0)) ) print *, c type is ( character (*) ) print *, c class default print *, 'unknown type' end select return end subroutine prn end program test
実行結果
1 1.000000 1.00000000000000 one 続行するには何かキーを押してください . . .
つづく