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 stuff
CONTAINS
CHARACTER*255 FUNCTION strtok ( source_string, delimiters )
[...]
END FUNCTION strtok
SUBROUTINE DO_SOMETHING ( )
CHARACTER(LEN=255) :: strtok
[...] !
END SUBROUTINE DO_SOMETHING
END MODULE MYMODULE
The strtok
function is a version of C's strings tokenizer, and I'll be using this function from the DO_SOMETHING
subroutine. I need to define strtok
, otherwise gfortran complains about it being not defined. However, if I do, and compile my code and link it to the main program, the linker complains about an undefined reference to strtok_
. I have no idea why this is the case, as they are both in the same module and should be visible. Other functions and subroutines in the same module don't have this problem. Is this something to do with the fact that this is a character*-returning function?
Judging from the incomplete source code you posted, I'm thinking this may be the offending line:
Since the subroutine
DO_SOMETHING
and the functionstrtok
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 functionstrtok
's type insideDO_SOMETHING
, but what actually happens is that this line declares a new character variable namedstrtok
in the scope of subroutineDO_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.
In the following, I'll explain using the complete example below (which you can compile and link to try things):
In the code of function
bar
, the declarationinteger :: foo
is strictly equivalent to:Thus, in the code of
bar
, you are explicitly stating:So, this is valid code, and the compiler just expect you to provide an
external
function namedfoo
. Because you don't (the module function isn't external), it fails to link. You can provide an externalfoo
function by adding the following code (not in the module, just at the end of the same file):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 ofbar
, symbolfoo
will resolve to the module function, which will then be called whether or not you provide an external function namedfoo
(thus, the output will be1
).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.