使用Fortran泛型接口的警告,其中包含虚拟段是无限多态指针的过程

时间:2014-11-03 17:34:45

标签: generics fortran polymorphism

我写了一个包含三个模块程序的通用接口

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):warning#6738:此特定过程的类型/等级/关键字签名与另一个共享相同通用名称的特定过程匹配。 [MESHR]

logical function MeshR(IVal)

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

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

logical function MeshC(IVal)

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

由于我们无法将一个具体类型的数据(如实数或复数)传递给函数或过程调用中的无限polomorhpic指针,我不太明白为什么编译器会给我这样的警告。但是,似乎这些警告不会在我的简单测试程序中造成任何问题。所以任何人都可以向我解释这些警告会发生什么,并且在某些情况下是否会引起任何严重问题?非常感谢。

2 个答案:

答案 0 :(得分:2)

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

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

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

因此,从特定过程选择的角度来看 - 因为无限多态对象与任何类型都是兼容的,所以在确定哪个特定过程应该被选择用于实际参数是真实的(4)或复杂的参考时存在歧义。 (4)。

当扩展接口时(即,声明接口时),编译器需要诊断这种不明确性,即使您对接口的实际使用不是模糊的。

(需要intent(in)指针或可分配参数在多态参数的声明类型中匹配的规则也比它们需要的更严格。如果它们在将来的修订中放宽,那么一定程度上可能会出现模糊的引用假参数消歧比其他要求更具限制性,将来可能会出现向后兼容的语言变化。)

答案 1 :(得分:1)

根据f2003标准:

  

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

因此无法解析界面(gfortran在该点返回错误)。所以无限多态可以有任何类型,包括真实。

在以下代码中,您可以看到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