fortran90のポインタの使い方がよくわかっていないので、テストプログラムを作成して実証してみる。
2つのファイルを用意して、モジュールのprivateな変数の演算結果をサブルーチンの引数を通して取得できるかテスト。
main.f90
program main use calc implicit none integer(kind=8) :: res integer(kind=8), pointer :: pnt allocate(pnt) call set_param res = 10 call calc_param(res) write(*,'(a, i5)') "res = ", res !res = 0 !call calc_pointer(res) !write(*,*) "res = ", res pnt = 10 call calc_param(pnt) write(*,'(a, i5)') "pnt = ", pnt pnt = 10 call calc_pointer(pnt) write(*,'(a, i5)') "pnt = ", pnt end program main
calc.f90
module calc implicit none private public set_param, calc_param, calc_pointer integer(kind=8) :: a, b contains subroutine set_param a = 1 b = 2 end subroutine set_param subroutine calc_param(c) integer(kind=8), intent(inout) :: c write(*,'(a, i5, a)') "c = ",c," !! in calc_param" c = a + b write(*,'(a, i5, a)') "c = ",c," !! in calc_param" end subroutine calc_param subroutine calc_pointer(c) integer(kind=8), pointer, intent(inout) :: c write(*,'(a, i5, a)') "c = ",c," !! in calc_pointer" c = a + b write(*,'(a, i5, a)') "c = ",c," !! in calc_pointer" end subroutine calc_pointer end module calc
FC=ifort OBJS=calc.o all: $(OBJS) main main: main.o $(OBJS) $(FC) $(FCFLAGS) -o $@ $^ clean: $(RM) *.o *.mod $(RM) main .SUFFIXES: .SUFFIXES: .o .f90 .mod .f90.mod: $(FC) -c -o $@ $< .f90.o: $(FC) -c -o $@ $<
4つのパターンを用意しています。
- 変数から変数に渡す
- 変数からポインタに渡す
- ポインタから変数に渡す
- ポインタからポインタに渡す
この内の3番目のポインタから変数に渡すのは、コンパイル時にエラーになってしまいます。引数がポインタで定義されていれば変数を渡すことは出来ないようです。
ifort -c -o main.o main.f90 main.f90(16): error #6691: A pointer dummy argument may only be argument associated with a pointer. [RES] call calc_pointer(res) --------------------^ compilation aborted for main.f90 (code 1) make: *** [main.o] Error 1
3番目をコメントアウトして実行した結果は、
c = 10 !! in calc_param c = 3 !! in calc_param res = 3 c = 10 !! in calc_param c = 3 !! in calc_param pnt = 3 c = 10 !! in calc_pointer c = 3 !! in calc_pointer pnt = 3
となりました。
ポインタを渡すときはサブルーチン側でもポインタでないといけないということがわかりました。
(ソースコードの間違いで予期しない結果になっていたのに気づいて修正しました4/24)