受け取る側では以下のようにコロンを用いた記述を行い、どのような大きさであっても 受け取れる用に記述しますとか知らなかった…ショック。
うーんでも明示してあったほうが読みやすいかな?
あと 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:
Post a Comment