为何Fortran/gfortran将函数参数识别为UNKNOWN类型?
Fortran抽象接口中嵌套接口导致参数类型识别失败的问题解决
问题原因
你在抽象接口method_interface内部嵌套定义func的接口,这种写法在gfortran 9.4中无法被正确解析:编译器无法识别func的过程类型,将其判定为UNKNOWN,进而导致重写的method函数出现参数类型不匹配错误,最终派生类因未正确实现延迟绑定过程而被要求声明为抽象类型。
修正方案
将func的接口单独提取为一个独立的抽象接口,在模块中提前声明,然后在method_interface和重写的method函数中直接引用该抽象接口作为func的类型。
修改后的代码
abstract_class.f90
module module_abstract_class implicit none ! 单独定义func的抽象接口 abstract interface pure function func_interface(a, b) result(ret) real, intent(in) :: a, b real :: ret end function func_interface end interface type, public, abstract :: abstract_class contains procedure(method_interface), pass(self), deferred :: method end type abstract interface pure function method_interface(self, func, a, b) result(ret) import abstract_class, func_interface class(abstract_class), intent(in) :: self procedure(func_interface) :: func ! 引用抽象接口作为类型 real , intent(in) :: a, b real :: ret end function end interface end module
extend_class.f90
module module_extend_class use module_abstract_class implicit none type, extends(abstract_class) :: extend_class contains procedure, public, pass(self) :: method end type contains pure function method(self, func, a, b) result(ret) class(extend_class), intent(in) :: self procedure(func_interface) :: func ! 直接引用抽象接口 real , intent(in) :: a, b real :: ret ret = func(a, b) end function method end module
main.f90(无需修改)
program i_love_fortran use module_extend_class type(extend_class) :: e print *, e%method(add, 1, 2) contains pure function add(a, b) result(ret) real, intent(in) :: a, b real :: ret ret = a + b end function end Program i_love_fortran
编译验证
使用原编译命令即可正常编译运行:
gfortran abstract_class.f90 extend_class.f90 main.f90
运行后会输出3.00000000。
说明
Fortran标准虽允许在函数内部嵌套接口,但旧版本gfortran(如9.4)对抽象接口内的嵌套接口支持不完善,无法正确识别其过程类型。将接口单独提取为抽象接口后,编译器可以明确识别参数的过程类型,解决类型不匹配问题。
内容的提问来源于stack exchange,提问作者masayoshiz
相关产品推荐
相关产品推荐

