I am new to Fortran and am curious about how to correctly 'wrap' subroutines.
E.g. suppose I have a main program that calls some subroutine outer
, that checks a flag and then calls some other subroutine, inner_1
or inner_2
, depending on the value of flag
. It passes arguments along to the inner subroutines.
Naively, I can just create a subroutine outer
than checks the flag and calls the inner subroutines. But this requires declaring all variables passed to outer
just to pass them along to the inner subroutines. For many arguments, this seems cumbersome.
Is this the standard way to accomplish this, or is there some better way that I don't know about?
I wrote a working example:
program main
use m_mod, only : outer
implicit none
real :: a = 1.0
integer :: b = 1
integer :: flag
flag = 1
call outer(a,b,flag)
flag = 2
call outer(a,b,flag)
end program main
module m_mod
implicit none
private
public :: outer
contains
subroutine outer(a,b,flag)
real, intent(in) :: a
integer, intent(in) :: b
integer, intent(in) :: flag
if (flag == 1) then
call inner_1(a,b)
else
call inner_2(a,b)
end if
end subroutine outer
subroutine inner_1(a,b)
real, intent(in) :: a
integer, intent(in) :: b
write(*,*) "inner_1-a", a
write(*,*) "inner_1-b", b
end subroutine inner_1
subroutine inner_2(a,b)
real, intent(in) :: a
integer, intent(in) :: b
write(*,*) "inner_2-a", a
write(*,*) "inner_2-b", b
end subroutine inner_2
end module m_mod
which outputs
inner_1-a 1.00000000
inner_1-b 1
inner_2-a 1.00000000
inner_2-b 1
as expected. I just want to know if there is a better way to do this!
If you want to keep the inner routines independent (i.e. they can be called from other routines than the wrapping one) there's no obvious other solution. Otherwise you may transform them into contained routines, without having to repeat the argument list:
module m_mod
implicit none
private
public :: outer
contains
subroutine outer(a,b,flag)
real, intent(in) :: a
integer, intent(in) :: b
integer, intent(in) :: flag
if (flag == 1) then
call inner_1()
else
call inner_2()
end if
CONTAINS
! a, b, (and flag), are available to the contained routines
! thanks to host association
subroutine inner_1()
write(*,*) "inner_1-a", a
write(*,*) "inner_1-b", b
end subroutine inner_1
subroutine inner_2()
write(*,*) "inner_2-a", a
write(*,*) "inner_2-b", b
end subroutine inner_2
end subroutine outer
end module m_mod