不定の輩
DO LOOP を抜けた時の loop 変数の値は FORTRAN 66 では不定でしたが、FORTRAN 77 以降では loop を抜けた時点での値になっています。
例えば、以下のようなプログラムの場合、i = 6 で do loop 脱出条件を満たすので、i=6 が出力されます。loop の途中で exit する場合もその時点での i の値を保ちます。
program loops implicit none integer :: i i = 99 do i = 1, 5 print *, 'loop' end do print *, 'i=', i end program loops
loop loop loop loop loop i= 6
一方 do concurrent や forall の場合は局所スコープとなって値は更新されません。さらに、これらの構造では、局所変数の宣言もできます。(局所変数の宣言は gfortran 13 でもまだ対応していません。)
program loops implicit none integer :: i, m(10) i = 6 do concurrent(i = 1:10) m(i) = i**2 end do print *, i forall (i = 1:10) m(i) = i**2 end forall print *, i do concurrent(integer :: k = 1:10) m(k) = k**2 end do print *, m(10) forall (integer:: k = 1:10) m(k) = k**2 end forall print *, m end program loops
6 6 100 1 4 9 16 25 36 49 64 81 100
同様の事は implied do loop でもあって、以前書いたように array constructor / DATA statement 中では局所的スコープを持ち局所的な変数宣言も可能です (f2018)、一方 I/O 文中では 非局所的なスコープを持ち局所的な変数宣言はできません。
参照: Modern Fortran Explained 赤本 §23.9
FORTRAN IV
興味深いことに、これらは FORTRAN IV での LOOP 脱出時の LOOP 変数の不定性にさかのぼると言えます。IBM の FORTRAN IV では、DO LOOP 中で LOOP 変数が使用されるかされないかで、LOOP 脱出時の LOOP 変数の値が変化します。これが FORTRAN 66 で LOOP 脱出時の LOOP 変数の値が不定とされている一因と思われます。
単なる n 回反復の場合、LOOP カウンタ変数がレジスタとかに置き換えられているのかもしれません。一方、DO LOOP 内で LOOP 変数が使用される場合は LOOP カウンタ変数を記述通り更新しているのでしょう。
IBM7094 emulator で試してみた結果
JOB card と 出力結果の一部
$JOB LOOP VARIABLE $EXECUTE IBJOB $IBJOB GO,LOGIC,MAP,FIOCS $IBFTC PRIME FULIST,REF,NODECK,M90 C C LOOP CHECK C I = 99 DO 10 I=1,5 WRITE(6,900) 10 CONTINUE C WRITE(6,901) I C DO 20 I=1,5 WRITE(6,901) I 20 CONTINUE C WRITE(6,901) I STOP C 900 FORMAT(6H LOOP1) 901 FORMAT(3H I=,I5) END
LOOP1 LOOP1 LOOP1 LOOP1 LOOP1 I= 99 I= 1 I= 2 I= 3 I= 4 I= 5 I= 5 511 LINES OUTPUT. $IBSYS $STOP