【问题标题】:Fortran compilation error - undefined referenceFortran 编译错误 - 未定义的引用
【发布时间】:2013-04-18 16:53:32
【问题描述】:

我正在尝试编译一个使用一堆模块的 fortran 程序。编译时出现错误,这让我发疯。该错误是由添加一个子程序引起的,并且在我尝试重新编译程序时发生:

主程序包含这两行:

--

call read_step(nStepOne,molOne)
call read_step(nStep,mol)

--

这是调用文件“fileio.f90”中的子例程之一:

--

subroutine read_step(n,tape)

implicit none

integer, intent(in) :: tape
integer, intent(out) :: n

character(len=6) :: dum

rewind(tape)
read (tape,*)
read (tape,*) dum, n
rewind(tape)
return
!
end subroutine read_step

--

当我尝试编译它时,出现以下错误:

ifort -o SpIdMD.x *.o -static-intel -openmp 
SpIdMD.o: In function `MAIN__':
SpIdMD.f90:(.text+0x3b2): undefined reference to `read_step_'
SpIdMD.f90:(.text+0x3c5): undefined reference to `read_step_'
make: *** [SpIdMD.x] Error 1

对同一模块中的子例程的其他调用没有给出任何错误,我只是看不出对“旧子例程”的调用与我刚刚创建的调用之间有任何区别。

这些“旧子程序”之一的示例是:

在主程序中:

call get_dim(n_atom,nSnap,mol)

在文件io.f90中:

subroutine get_dim(n,n_snap,tape)

implicit none

integer,intent(in) :: tape
integer,intent(out) :: n, n_snap
integer :: m

rewind(tape)
read (tape,*,err=1,end=2) n
rewind(tape)

m = 0
do while (.true.)
   read (tape,*,err=1,end=3)
   m = m +1
end do
3   n_snap = m/(n + 2)
if (m.ne.(n_snap*(n + 2))) stop  'unexpected end of input file'

rewind(tape)

return
!
1   stop 'error in input file'
2   stop 'unexpected end of input file'
end subroutine get_dim

我完全不知道为什么会出现这种行为。如果有人能帮助我解决这个噩梦,我将不胜感激。谢谢!

【问题讨论】:

  • 您是否运行过make clean,然后再次尝试make
  • 是的,但没有解决任何问题。我确保更新了 fileio.o(包含模块)。

标签: fortran


【解决方案1】:

如果子程序read_step的定义在一个模块中,那么你要么忘记在主程序顶部添加该模块的USE语句,要么模块中的相关程序不是PUBLIC。

对于该编译器(和其他一些编译器),模块过程的链接器名称通常由模块名称后跟“mp”(大小写可能不同)后跟过程名称组成,并带有不同数量的前导和尾随下划线加盐调味。您的链接器错误没有任何“修饰”,这表明在使用过程引用编译范围时,编译器认为该过程不是模块过程。

【讨论】:

  • 非常感谢伊恩!你解决了我的问题。感谢您的评论意识到没有将相关子例程的名称添加到模块顶部的“公共”标签中。
【解决方案2】:

更具体地说,我将展示如何使用另一个答案中提到的 USE 和 PUBLIC 语句。

我这样包装了我的 F77 函数:

  module mod
  contains
  FUNCTION FUNC(PARAM)
  ...
  END
  end module mod

虽然旧代码 (1986) 是大写,而我的代码是小写。 这编译得很好。您可以在modulecontains 之间添加public func。但这似乎是默认设置,因此您不需要它。

链接时你需要像这样传递你的程序和库:gfortran -o prog prog.for mod.for(或者.o,如果之前编译过)。

【讨论】:

  • 这应该是一个问题,而不是一个答案。当您使用模块编译源代码时,会生成一个目标文件 (.o)。您是否将此目标文件提供给后面的链接步骤?
  • 我知道,我发布了一个问题:stackoverflow.com/questions/32278178/… 将删除此问题,或将其更新为真正的答案。 ;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-12-25
  • 1970-01-01
  • 2016-06-23
  • 2016-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多