2011-04-17

Fortran 90で配列の上下限を省略してコロンを使うことについて

http://www.nag-j.co.jp/fortran/FI_12.html
受け取る側では以下のようにコロンを用いた記述を行い、どのような大きさであっても 受け取れる用に記述します
とか知らなかった…ショック。
うーんでも明示してあったほうが読みやすいかな?
あと size(x) も使える場面ありそうだなぁ…。


追記:
どうもコロンでやってしまうと subroutine 側では勝手に 1: になってしまうようだ。危なすぎ。当然使用禁止だわ。

たとえば

real(8) :: hoge(2:3)

があって、これを

call fuga( hoge = hoge ) !! intent(in)

と読ませたとする。このとき、

subroutine fuga( hoge )
  real(8), intent(in) :: hoge( : )
  
  write(*,"('hoge(',i2,':',i2)')") lbound(hoge,1), ubound(hoge,1)
  
  return
endsubroutine

とすると、
hoge( 1: 2)
と出力される。めっちゃ危険じゃん…。


[2013-04-01追記]
「下限だけ指定してコロン」が最強かも。

参考:
http://d.hatena.ne.jp/rontas/20130113/1358047540
[/追記]


[2012-11-19追記]
ついさっき、これと似てるけどちょっと違うミスをしていた。若干簡略化して以下に説明する。

まず呼び出し側では、

integer, parameter :: imax=100
integer, parameter :: jmax=100
real(8) :: po(-1:imax+1,-1:jmax+1)

  call subroutine1( pt = po(:,:) ) !! intent(in)
<以下略>

のように書いていた。でもって呼ばれる側は、

subroutine1( pt )
implicit none
real(8), intent(in) :: pt(imax,jmax)
<以下略>

としていた。意図としてはもちろん、pt(1:imax, 1:jmax) = po(1:imax,1:jmax) であってほしかった。ところがこの場合、g95 でも ifort (ver13) でも pt(-1:imax-1,-1:jmax-1) が入ってしまう。正しくは、

  call subroutine1( pt = po(1:imax,1:jmax) ) !! intent(in)

とすべきだった。あるいは、配列をケチらずに

  real(8), intent(in) :: pt(-1:imax+1,-1:jmax+1)

と書いてもよかった。いずれにせよ、配列の一部だけを渡すときは要注意、ということだ。
[/追記]

No comments: