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.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…