gfortran因特定的多态性而失败

时间:2013-09-08 12:00:17

标签: polymorphism fortran gfortran

我有一个基类型,其中包含一个将用户定义的函数作为输入的过程。用户定义的函数在扩展类型中定义。以下使用ifort-13.1.3进行编译,但使用gfortran-4.8.1进行编译:

module m

 implicit none

 type, abstract :: base
  contains
   procedure :: use_f
 end type base

 type, extends(base) :: extended
  contains
   procedure :: f     
   procedure :: test ! calls use_f which takes f as argument
 end type extended

contains
 subroutine f(this)
  class(extended) :: this
 end subroutine f

 subroutine use_f(this, func)
  class(base) :: this
  interface
   subroutine func(this)
    import :: base
     class(base) :: this
   end subroutine func
  end interface
 end subroutine use_f

 subroutine test(this)
  class(extended) :: this
  call this%use_f(f) ! This is the important part!
 end subroutine test
end module m

program a
end program a

gfortran生产

     call this%use_f(f)
                1
Error: Interface mismatch in dummy procedure 'func' at (1): Type/rank mismatch in argument 'this'

我也尝试过使用过程指针,但是当gfortran失败时仍然编译ifort。现在,如果不是接口块我放

external func

进入use_f代码使用ifort和gfortran成功编译。但是,EXTERNAL关键字不会变得过时吗?是否有更符合标准的方法有效?

1 个答案:

答案 0 :(得分:6)

提出的程序有误。虽然从技术上讲,编译器不需要发出诊断,但我希望ifort应该,但在某些情况下这可能是合理的扩展。我建议向英特尔报告错误。

正如gfortran错误消息所暗示的那样,实际过程参数和虚拟过程参数的特征并不相同。当假人的界面是明确的时,它们必须与F2008的12.5.2.9p1相同,这里禁止一些例外情况。过程的特征包括其参数的特征。伪数据参数的特征包括其类型。

实际过程中伪参数的类型为extended,虚拟过程中伪参数的类型为base

可能令人困惑的问题是,如果您实际上使用func描述的接口调用过程,则将extended类型的对象作为实际参数传递给该过程是有效的程序。但仅仅因为base类型与extended类型兼容,才会使类型相同。

当伪过程参数的接口是隐式的(比如因为您使用了EXTERNAL语句),则放宽了匹配特性的规则。也就是说,具有多态参数的过程必须具有显式接口,因此无法使用伪过程参数。

外部语句不是过时的,但如果始终提供显式接口则不需要(这是一种很好的做法)。

请注意,您将f作为extended的绑定和模块过程。当您引用f作为实际过程参数时,您指的是模块过程,而不是绑定。在您显示的代码中,没有必要将f作为绑定。为了确保没有混淆 - 过程与绑定到过程的类型之间关系的性质在Fortran中与其他语言(如C ++)中使用的模型不同。程序永远不是类型的成员,绑定是。完全不同类型的绑定可以参考相同的过程。