Rodolfo Batista Negri
Rodolfo Batista Negri

Reputation: 23

How to make a generic procedure pointer in Fortran?

I am a low level Fortran programmer. I am trying to make subroutines as generic as possible and I wonder if I can send an information of which subroutine another subroutine should acces from a given information in the main program. For instance, if I have:

program main
use test
implicit none
real(8) X
end program main

And:

module test

contains

subroutine A (X)
real(8) X
X = 2*X
end subroutine A

subroutine B (X)
real(8) X
X = 3*X
end subroutine B

end module test

I would like to, given the subroutine name 'A' or 'B' in the main program, transfer this to a third subroutine C inside the module test, which in turn would make some calculations and use the transferred name to choose between A and B in its calculations.

I know if I build the calculations of that subroutine C inside the main program, I can use a procedure pointer to access either A or B subroutines. However, I need to have the subroutine C. So I guess I will have a subroutine C with built in procedure pointer and it will take the name given in the main program as an argument. But I do not know how to do that. Neither if it is possible. If it is not, is there any other way? I do not know, maybe the subroutine C reading a txt file associating the read name to the procedure pointer. But, how?

Thank you, in advance!

Upvotes: 1

Views: 419

Answers (1)

jme52
jme52

Reputation: 1123

I think that what you want is this: you first define subroutines A and B

module ab_m
  implicit none
contains

  subroutine A(X)
    real, intent(inout) :: X
    X = 2 * X
  end subroutine A

  subroutine B(X)
    real, intent(inout) :: X
    X = 3 * X
  end subroutine B

end module ab_m

Then subroutine C uses a dummy procedure, specified by an interface,

module c_m
  implicit none
contains

  subroutine C(sub,y)

    interface
       subroutine sub(p)
         implicit none
         real, intent(inout) :: p
       end subroutine sub
    end interface

    real, intent(inout) :: y
    y = y + 1
    call sub(y)

  end subroutine C

end module c_m

and the main program chooses what procedure to use in C:

program p

  use ab_m 
  use c_m
  implicit none
  real :: z(2)

  z = 1.0
  call C(B, z(1))        
  call C(A, z(2))
  write(*,*) z     ! writes 6.0, 4.0 [ (1+1)*3, (1+1)*2) ]

end program p

Upvotes: 2

Related Questions