Search code examples
fortrangfortran

Undefined reference to module subroutines matching an abstract interface


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?


Solution

  • 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.