Fortran泛型接口包含伪参数为无限多态指针的过程,该接口发出警告



我编写了一个通用接口,其中包含三个模块过程

module MTest
  implicit none
  interface Mesh
    module procedure :: MeshG,MeshR,Meshc
  end interface Mesh
  contains
    logical function MeshR(IVal)
      real(4),intent(in) :: IVal
      MeshR=.true.
    end function MeshR
    logical function MeshC(IVal)
      complex(4),intent(in) :: IVal
      MeshC=.true.
    end function MeshC
    logical function MeshG(IVal)
      class(*),pointer,intent(in) :: IVal
      MeshG=.false.
    end function MeshG
end module MTest
program main
  use MTest
  implicit none
  real(4) :: a
  write(*,*) Mesh(a)
end program main

当我用ifort编译它时,编译器会给我两条警告:

Test.f90(8):警告#6738:此特定过程的类型/等级/关键字签名与共享相同通用名称的另一个特定过程匹配。[MESHR]

logical function MeshR(IVal)

---------------------^

Test.f90(13):警告#6738:此特定过程的类型/等级/关键字签名与共享相同通用名称的另一个特定过程匹配。

logical function MeshC(IVal)

---------------------^

由于我们不能在函数或过程调用中将具体类型的数据(如实数或复数)传递给无限的polomorhpic指针,我不太明白编译器为什么会给我这样的警告。然而,这些警告似乎不会在我的简单测试程序中引起任何问题。那么,有人能向我解释一下这些警告是怎么回事吗?在某些情况下,它们会造成严重问题吗?非常感谢。

(对以下内容进行了材料编辑,因为我忘记了F2008 12.5.2.5p2中的限制。)

为泛型引用选择适当的特定过程的规则没有考虑当前对指针和可分配伪参数的限制,这些参数需要在声明的类型中匹配。

在Fortran 2003中,规则甚至不考虑伪参数的可分配性或指针性质。F2003中的具体过程选择是基于实际参数的数量、名称和类型+种类+等级。

因此,从特定程序选择的角度来看——因为一个无限多态对象与任何东西都是类型兼容的,所以在实际参数是真实的(4)或复杂的(4。

当接口被扩展时(即,当接口被声明时),即使您对接口的实际使用没有歧义,编译器也需要诊断这种歧义。

(要求intent(in)指针或可分配参数在多态参数的声明类型中匹配的规则也比需要的更严格。如果在未来的修订中放宽这些规则,那么模糊引用肯定是可能的。)。与其他要求相比,让伪参数消歧更具限制性,这就有可能在未来发生向后兼容的语言更改。)

根据f2003标准:

非多态实体的类型仅与相同声明类型的实体兼容。不是无限多态实体的多态实体与相同声明类型或其任何扩展的实体类型兼容即使一个无限多态实体不被认为具有声明的类型,它也是与所有实体兼容的类型。如果一个实体与类型的实体类型兼容,则该实体被称为与该类型类型兼容

因此无法解析该接口(gfortran此时返回一个错误)。因此,无限多态性可以有任何类型,包括real。

在下面的代码中,您可以看到一个示例,其中CLASS(*), pointer变量具有实数类型

module mod1
  implicit none
contains
    function fun1(x)
      real,target       :: x
      class(*), pointer ::fun1
      fun1 => x
    end function
    function fun2(IVal)
      class(*),pointer,intent(in) :: IVal
      logical fun2
       fun2=.false.
      select type(IVal)
         type is (real)
            print*, 'type is real'
            fun2 = .true.
      end select
    end function fun2
end module mod1
program main
  use mod1
  implicit none
  real     :: a
  write(*,*) fun2(fun1(a))
end program main

退货:

 type is real
 T

最新更新