我在看起来像这样的模块中有一个函数(以防有人感兴趣,就是这个函数)
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
Run Code Online (Sandbox Code Playgroud)
该strtok函数是C的字符串标记器的一个版本,我将在DO_SOMETHING子例程中使用此函数。我需要定义strtok,否则gfortran抱怨它未定义。但是,如果我这样做了,然后编译我的代码并将其链接到主程序,则链接器会抱怨未定义对的引用strtok_。我不知道为什么会这样,因为它们都在同一个模块中并且应该可见。同一模块中的其他函数和子例程不存在此问题。这与返回字符*的功能有关吗?
在下面的内容中,我将使用下面的完整示例进行说明(您可以编译并链接该示例):
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
Run Code Online (Sandbox Code Playgroud)
在函数代码中bar,声明integer :: foo严格等于:
integer, external :: foo
Run Code Online (Sandbox Code Playgroud)
因此,在的代码中bar,您明确声明:
“您可能已经有了名称的符号
foo,但是从现在开始,当我使用它时,我的意思是它是该名称的外部功能”
因此,这是有效的代码,编译器只希望您提供external名为的函数foo。因为您不这样做(模块功能不是外部的),所以它无法链接。您可以foo通过添加以下代码来提供外部功能(不在模块中,仅在同一文件的末尾):
integer function foo ()
foo = 42
end function
Run Code Online (Sandbox Code Playgroud)
如果添加此函数主体,则代码将被编译,并且输出将为42(由于调用了外部函数,而不是模块函数)。
同样值得注意的是,如果您integer :: foo在的代码中将行注释掉bar,则symbol foo将解析为模块函数,无论您是否提供名为的外部函数,该函数都会被调用foo(因此,输出为1)。
结论:不是编译器错误,而是滥用语言的旧功能(外部声明)。老实说,我认为最好将external声明明确标记为这样,这样至少可以在此处突出显示该问题。
| 归档时间: |
|
| 查看次数: |
1835 次 |
| 最近记录: |