我正在使用两个 Fortran 模块。第一个包含子程序 foo :

module fmod1

  contains

  subroutine foo(i)
    implicit none

    integer, intent(inout) :: i

    i=i+1

  end subroutine foo

end module fmod1

第二个还包含一个名为 foo 的子程序,它调用第一个模块的 foo ,重命名为 foo_first :
module fmod2
  use fmod1, only : foo_first => foo

  contains

  subroutine foo(i)
    implicit none

    integer, intent(inout) :: i

    i=i+2
    call foo_first(i)

  end subroutine foo

end module fmod2

当我用 gfortran 编译它们以获得两个目标文件,然后用 nm 查看它们的内部时,我看到了预期的结果:
fmod1.o:
0000000000000020 s EH_frame1
0000000000000000 T ___fmod1_MOD_foo

fmod2.o:
0000000000000030 s EH_frame1
                 U ___fmod1_MOD_foo
0000000000000000 T ___fmod2_MOD_foo

然后我在编写 Fortran 程序时没有问题,该程序加载第二个模块并调用其中的 foo ( ___fmod2_MOD_foo ,它本身调用 ___fmod1_MOD_foo )。

当我尝试使用 iso_c_binding 从 C 程序做同样的事情时,我的问题就出现了。我通过将 bind(c) 添加到子例程来更改第二个模块:
module fmod2
  use iso_c_binding
  use fmod1, only : foo_first => foo

  contains

  subroutine foo(i) bind(c)
    implicit none

    integer, intent(inout) :: i

    i=i+2
    call foo_first(i)

  end subroutine foo

end module fmod2

再次在目标文件上运行 nm 现在给出:
fmod1.o:
0000000000000020 s EH_frame1
0000000000000000 T ___fmod1_MOD_foo

fmod2.o:
0000000000000030 s EH_frame1
0000000000000000 T _foo

即,第二个模块似乎不再需要第一个模块。当我尝试尝试从 C 程序的第二个模块调用 foo 时,很明显子例程不是从第一个模块调用 foo,而是在无限循环中调用自身。

这是一个错误,还是我做了一些我不应该做的事情?

最佳答案

现在是 GCC Bug 79485 。我之前已经报告过非常相似且很可能相关的错误( ICE with binding-name equal to the name of a use-associated procedureWrong subroutine called, clash of specific procedure name and binding-name )。不幸的是,gfortran 开发人员很少,而且很忙,还没有解决这个问题。如果他们看到其他人遇到它,他们可能会优先考虑它。

关于gcc - 使用 iso_c_binding 时重命名 Fortran 模块中的子例程,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42189625/

10-14 16:11
查看更多