使用 iso_c_binding 时重命名 Fortran 模块中的子例程

Renaming a subroutine in a Fortran module when using iso_c_binding

我正在使用两个 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,而是在无限循环中调用自身。

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

当您将 BIND(C) 添加到过程中时,您是在(间接地)指定绑定名称,而不是编译器应用它自己的规则(包括模块名称)。

不是"the second module no longer seems to require the first module",而是您更改了第二个模块中例程的绑定名称。您还没有在第一个模块中触及 foo 的绑定名称(由于重命名,这不是它的本地名称。)

也就是说,编译器应该知道第一个模块中 foo 的绑定名称,通过它的本地名称引用,并在调用的对象中放入正确的名称。根据其他评论者的说法,您使用的 gfortran 版本可能在此处存在错误。试试更新的。

现在是 GCC Bug 79485. I have already reported very similar and very probably related bugs before (ICE with binding-name equal to the name of a use-associated procedure and Wrong subroutine called, clash of specific procedure name and binding-name)。不幸的是,gfortran 开发人员只有少数而且非常忙,还没有解决这个问题。如果他们看到其他人遇到它,他们可能会考虑稍微高一些的优先级。