gfortan 接口不明确的问题

Problem with Ambiguous interfaces with gfortan

我的情况类似于以下代码片段(保存在 test.f90 中):

module interfaces_mod

    private
    
    public :: interf

    interface interf
        module procedure interf1
        module procedure interf2
    end interface

    contains
        subroutine interf1(&
                        numbers,&
                        num_numbers,&
                        dense_ranks&
                        )
            Implicit None
            integer, dimension(:), intent(in) :: numbers
            integer, intent(in) :: num_numbers
            integer, dimension(:), intent(out), optional :: dense_ranks
        end subroutine interf1

        subroutine interf2(&
                        degeneracies,&
                        numbers,&
                        num_numbers,&
                        dense_ranks&
                        )
            Implicit None
            Integer, dimension(:), intent(inout) :: degeneracies
            integer, dimension(:), intent(in) :: numbers
            integer, intent(in) :: num_numbers
            Integer, dimension(:), intent(out), optional :: dense_ranks
        end subroutine interf2
end module interfaces_mod

因此,该模块定义了具有两种可能实现的通用接口。

可以使用 ifort 和

编译此片段

ifort -c -o "test.o" "test.f90"

创建模块。 但是尝试使用 gfortran 编译相同的代码:

gfortran -c -o "test.o" "test.f90"

导致错误:


   15 |         subroutine interf1(&
      |                          1
......
   32 |         subroutine interf2(&
      |                          2
Error: Ambiguous interfaces in generic interface 'interf' for ‘interf1’ at (1) and ‘interf2’ at (2)

现在查看实现的虚拟参数,调用 interf1 一个整数数组,后跟一个整数和一个可选的整数数组。 interf2 而是使用两个 Integer 数组调用,后跟一个 Integer 和一个可选的 整数数组。 所以我不明白歧义是从哪里来的,为什么ifort可以编译这个片段而gfortran不能编译它。

gfortran 版本为 9.3.0, ifort 版本是 19.0.5.281

您的程序不符合具有相同泛型标识符的规则,gfortran 有权拒绝该泛型。

要考虑的约束条件是Fortran 2018的C1514,具体看一下吧。没有伪过程或传递对象伪参数,所以我们只剩下该约束的 (1) 和 (4)。必须满足其中一个条件。

对于 (1):

  • 我们在每个过程中都有一个标量参数,在每个过程中称为 num_numbers。标量参数不能用于消除歧义。

  • interf1 中,两个数组虚拟参数的 (1a) 得分为 1,而每个参数的 (1b) 得分为 3。对于 interf2 (1a) 三个数组虚拟对象的分数为 2,而 (1b) 每个虚拟对象的分数也为 2。

(1) 不满足。

对于 (4):

  • 一个过程中的伪参数与另一个过程中同名的伪参数没有区别。
  • interf1 没有名称未出现在 interf2 中的虚拟参数。
  • interf2 在位置 1 有名称消除歧义参数 degeneracies 而它的第一个位置消除歧义参数在位置 2.

(4) 不满足。

虽然不满足 (4),但很容易修改过程定义,例如:将 degeneracies 移到参数列表的后面。

Fortran 标准本身有一个重要说明,在您尝试弄清楚如何创建一个不明确的引用之前:

These rules are sufficient to ensure that references to procedures that meet them are unambiguous, but there remain examples that fail to meet these rules but which can be shown to be unambiguous [...] The rules to cover all cases are too complicated to be useful.