Why is this a function declared inside the module and then used somewhere else in the same module not seen by the linker?

前端 未结 2 1015
感情败类
感情败类 2020-11-30 14:46

I have a function (in case anyone is interested, it is this function) in a module that looks like this

MODULE MYMODULE

    IMPLICIT NONE
    ! Some random s         


        
相关标签:
2条回答
  • 2020-11-30 15:01

    In the following, I'll explain using the complete example below (which you can compile and link to try things):

    module mymodule
    contains
      integer function foo ()
        foo = 1
      end function
    
      integer function bar ()
        integer :: foo
        bar = foo()
      end function
    end module
    
    program test
      use mymodule
      print *, bar()
    end
    

    In the code of function bar, the declaration integer :: foo is strictly equivalent to:

    integer, external :: foo
    

    Thus, in the code of bar, you are explicitly stating:

    "there may already be a symbol of name foo accessible to you, but from now on, when I use it I mean it to be an external function of this name"

    So, this is valid code, and the compiler just expect you to provide an external function named foo. Because you don't (the module function isn't external), it fails to link. You can provide an external foo function by adding the following code (not in the module, just at the end of the same file):

    integer function foo ()
      foo = 42
    end function
    

    If you add this function body, then your code will compile, and the output will be 42 (as the external function is called, not the module function).

    Also worth noting, if you comment out integer :: foo line in the code of bar, symbol foo will resolve to the module function, which will then be called whether or not you provide an external function named foo (thus, the output will be 1).

    Conclusion: not a compiler bug, but misuse of an old feature of the language (external declarations). To be honest, I think it's better to explicitly mark your external declarations as such, which would at least have highlighted the issue here.

    0 讨论(0)
  • 2020-11-30 15:19

    Judging from the incomplete source code you posted, I'm thinking this may be the offending line:

    CHARACTER(LEN=255) :: strtok
    

    Since the subroutine DO_SOMETHING and the function strtok are in the same module, they automatically know about each other's definition (they have an explicit interface). This means it is not only unnecessary to redeclare the function strtok's type inside DO_SOMETHING, but what actually happens is that this line declares a new character variable named strtok in the scope of subroutine DO_SOMETHING, overruling the module function with the same name.

    Basically, inside the subroutine, the identifier strtok refers to a variable, so when you try to refer to a function by that name, the compiler doesn't know about it.
    Hmm, now that I'm writing this, I'm starting to think this should give a compile time error, not a linking error. Still, might be worth it to try and comment out the line I mentioned and give it a go.

    0 讨论(0)
提交回复
热议问题