【问题标题】:Declare functions as variables in Fortran90 modules? ifort says yea, gfortran says nay在 Fortran90 模块中将函数声明为变量? ifort 说是,gfortran 说不是
【发布时间】:2015-05-24 14:33:16
【问题描述】:

我目前正在两个不同的编译器上测试 Fortran 模块(Linux 机器上的 ifort,mac 上的 gfortran),我遇到了一个我无法解释的奇怪问题。

我有一个简单的模块,它有一个公共子例程和它调用的两个私有函数。它看起来像这样:

module test
implicit none
private
public :: publicsub

contains

subroutine publicsub(x,y,arg)
implicit none
integer(kind=4), intent(in):: x,y
real(kind=8),   intent(out):: arg

arg = func1(x)*10. / func2(y)

end subroutine publicsub

integer(kind=4) function func1(x)
implicit none
integer(kind=4), intent(in):: x

func1 = x*x;

end function func1

integer(kind=4) function func2(x)
implicit none
integer(kind=4),intent(in):: x

func2 = x*x*x

end function func2
end module test

这是要测试的主程序:

program sgtest

use test

implicit none  
integer(kind=4) :: a,b
real(kind=8) :: output

a = 3
b = 4

call publicsub(a,b,output)

write *, output

end program sgtest 

我可以让模块自己使用 ok 进行编译。当我编译主程序时,它不会在我的 linux 机器上的 ifort 编译器下编译,除非我还在主子程序 publicsub 中将函数调用声明为整数,即,我将此代码添加到 publicsub:

integer(kind=4) :: func1,func2

然后它就可以正常工作了。但是,当我在我的 mac 上的 gfortran 上编译它时,我收到了这些错误消息:

架构 x86_64 的未定义符号:

 "_func1_", referenced from:
     ___test_MOD_publicsub in ccnj2Zt6.o
 "_func2_", referenced from:
     ___test_MOD_publicsub in ccnj2Zt6.o

ld:未找到架构 x86_64 的符号 collect2:错误:ld 返回 1 个退出状态

但是当我注释掉这个声明时,所有的东西都会按照 gfortran 的预期编译和运行。具有讽刺意味的是,我在没有这些声明的 linux 机器上从 ifort 收到了类似的错误消息。

那么这里发生了什么?这是 Fortran90/95 vs GNU Fortran 扩展问题,还是我在结构上做了一些对模块不适用的事情?

【问题讨论】:

  • 显示你的主程序。你 USE 模块正确吗?您绝对不应该添加该行。另请参阅stackoverflow.com/questions/3170239/… 为什么不使用(kind=4)
  • 也不要使用标签fortran90,没有通用标签fortranfortran90 仅用于针对这个有点旧的版本的具体问题。
  • 弗拉基米尔,我将添加主程序。抱歉,我之前没有包括在内。
  • 你公开声明中的单冒号是错字吗?
  • @Vladimir F:感谢您提供关于 (kind=4) 的提示。我使用从 f77 移植的大量遗留代码,其中有大量的 integer*4 和 (kind=4) (以及其他类型)。

标签: fortran gfortran intel-fortran


【解决方案1】:

我们不能知道您在原始代码中做错了什么,因为您没有显示您的主程序。但是从标题中回答问题:

当你这样做时:

subroutine publicsub(x,y,arg)
  integer(kind=...), intent(in):: x,y
  real(kind=...),   intent(out):: arg
  !!
  integer(kind=...) :: func1,func2
  !!

  arg = func1(x) * 10 / func2(y)

end subroutine publicsub

您声明,func1func2 与模块中的 func1func2不同的外部函数。

并且由于您在模块之外没有这样的外部函数,链接器无法找到它们并且链接以错误结束。

添加的行绝对不应该在那里。

【讨论】:

  • 弗拉基米尔,感谢您的回复。那么为什么 ifort 只有在我添加这个声明时才起作用呢?这才是真正的问题。
  • @txpaulm 谁知道,我们没有水晶球,也看不到屏幕上的错误消息和您的命令。
  • @txpaulm 这意味着,如果你想要解释,你应该给他们看。
  • 好的,当我可以回到那台机器上时,我将发布 ifort 编译器的错误消息(与办公室的网络连接现在已关闭)。
  • 我很尴尬,但我才发现我做错了什么!它在编译中!我之前编译了这个模块只是为了测试它以确保语法没问题。即:
猜你喜欢
  • 1970-01-01
  • 2020-08-23
  • 2021-12-25
  • 1970-01-01
  • 1970-01-01
  • 2023-03-06
  • 1970-01-01
  • 1970-01-01
  • 2013-07-22
相关资源
最近更新 更多