追記: -fcheck=all オプションで回避できることがわかったので、セキュリティタグをはずしました。
いまどきfortranが表でガンガン動いてるなんてことはないと思うので、セキュリティタグが正しいかはわからないです…
コンパイラはgfortranです。
普通は配列外参照なんて書かない(動かす前に気づく)と思うんですが、時たま事故的に配列外参照が出ることはなくもなく、そのときにちょっとびっくりな挙動をしたのでメモ。
結論だけいえば、配列外参照をしてもエラーで停止しない場合が多々あります。
ローカル配列の配列外参照
program main
double precision array(10)
array = 100
do i =1, 15
write(*,*) array(i)
end do
end program
100.00000000000000
100.00000000000000
100.00000000000000
100.00000000000000
100.00000000000000
100.00000000000000
100.00000000000000
100.00000000000000
100.00000000000000
100.00000000000000
2.2348460840167035E-314
2.5463949491583268E-313
6.9531188553868160E-310
2.2348286607917029E-314
6.9531188553883970E-310
今回実行した限りでは、**配列外参照しても咎められません。**が、環境によってはsegmentation fault的なものをはいてとまることもあります。どういうことなんだ。
モジュール配列の配列外参照
module global
double precision array(10)
end module
program main
use global
array = 100
do i =1, 15
write(*,*) array(i)
end do
end program
んで、これをコンパイルしてみると…なんのエラーもなく通ります
さらにこれを実行すると…
100.00000000000000
100.00000000000000
100.00000000000000
100.00000000000000
100.00000000000000
100.00000000000000
100.00000000000000
100.00000000000000
100.00000000000000
100.00000000000000
0.0000000000000000
0.0000000000000000
0.0000000000000000
0.0000000000000000
0.0000000000000000
やはり配列外参照をしてるのに咎められることがないんですね…なんてこった…
かなり危険な挙動だと思います。実際これが原因で出力値がうまくいかないエラーに当たりました。OSやマシンによってメモリの割当は時々変わりうるので、再現性も低く、知らないとかなり原因が特定しにくかったです。
いまどき配列外参照が咎められないとは思いませんし…
fortranはどうにもヒープとかそんな概念以前の言語らしく、メモリ管理が後の言語とかなり違うために起こるんでしょうか...