I'm trying to create a module which has subroutine taking another subroutine's name as argument. Here is a main program (main.for):
program testmod
use action_mod
call main
end program testmod
And here is an example of my module (action_mod.for):
module action_mod
abstract interface
subroutine sub_interface(aA, aB)
integer aA, aB
intent(in) aA
intent(out) aB
end subroutine
end interface
contains
subroutine main
procedure(sub_interface) sub2,sub1
call action(sub1)
call action(sub2)
end subroutine
subroutine action(sub)
procedure(sub_interface) sub
integer argA, argB
argA = 10
call sub(argA, argB)
write(*,*) argA," > ",argB
end subroutine
subroutine sub1(i,o)
integer i,o
o = 100
return
end subroutine sub1
subroutine sub2(i,o)
integer i,o
o = 200
return
end subroutine sub2
end module action_mod
Whe I compile the code with
gfortran -o main action_mod.for main.for
I get an error
/tmp/ccdSM11U.o: In function `__action_mod_MOD_main':
action_mod.for:(.text+0x1a2): undefined reference to `sub1_'
action_mod.for:(.text+0x1b1): undefined reference to `sub2_'
collect2: error: ld returned 1 exit status
But when I put subroutines sub1(i,o)
and sub2(i,o)
into the main.for everything works fine. However this is not what I want.
Could you help me to find a correct way of creating a module? What is wrong with my code?
You have much the same problem as in this other question, so read answers there for more detail. However, this case has some extra complexity which is worth considering.
In the subroutine main
the statement
procedure(sub_interface) sub2,sub1
says that there are external procedures sub2
and sub1
. The module subroutines sub1
and sub2
of the module action_mod
are not these external procedures. In terms of the linked question, this is like having the declaration character(255) strtok
"hiding" the module function strtok
.
You should remove that statement from the subroutine.
But you have additional errors to fix. The module subroutines sub1
and sub2
do not have the same interface as the abstract interface sub_interface
. You need to ensure that the intent attributes for the dummy arguments of sub1
and sub2
, i
and o
match, those of the sub_interface
.