如何判断Fortran过程指针是否关联特定子程序
判断Fortran过程指针关联的具体子程序方法
你遇到的associated函数报错问题,本质是旧版Fortran标准(比如Fortran 95)不允许把具体子程序作为associated的第二个参数——这个特性是Fortran 2003才引入的。下面分两种场景给你解决办法:
场景一:用支持Fortran 2003+的编译器(推荐)
如果能升级你的gfortran到5.x及以上版本,或者使用Intel Fortran等对新标准支持较好的编译器,就可以直接用标准的associated函数来判断过程指针关联的具体子程序。
比如你可以这样写代码:
module boundary_mod implicit none ! 定义抽象接口 abstract interface subroutine boundary_interface() end subroutine boundary_interface end interface ! 声明过程指针 procedure(boundary_interface), pointer :: bc => null() contains subroutine boundaryA() print *, "This is boundaryA" end subroutine boundaryA subroutine boundaryB() print *, "This is boundaryB" end subroutine boundaryB end module boundary_mod program test_proc_ptr use boundary_mod implicit none ! 关联到boundaryA bc => boundaryA ! 直接用associated判断关联的具体子程序 if (associated(bc, boundaryA)) then print *, "bc is associated with boundaryA" else if (associated(bc, boundaryB)) then print *, "bc is associated with boundaryB" else print *, "bc is not associated" end if ! 切换到boundaryB bc => boundaryB if (associated(bc, boundaryA)) then print *, "bc is associated with boundaryA" else if (associated(bc, boundaryB)) then print *, "bc is associated with boundaryB" else print *, "bc is not associated" end if end program test_proc_ptr
编译的时候记得启用Fortran 2003及以上标准,比如用gfortran的话:
gfortran -std=f2003 test.f90 -o test
场景二:适配旧版编译器(比如你的gfortran 4.8.2)
如果暂时没法升级编译器,那就得用替代方案:给每个子程序加一个唯一的“标签”,通过额外的指针或者变量来记录当前关联的是哪个子程序。比如下面的写法:
module boundary_mod implicit none ! 定义两个抽象接口:一个是子程序接口,一个是标签函数接口 abstract interface subroutine boundary_interface() end subroutine boundary_interface integer function tag_interface() end function tag_interface end interface ! 过程指针和对应的标签指针 procedure(boundary_interface), pointer :: bc => null() procedure(tag_interface), pointer :: bc_tag => null() contains subroutine boundaryA() print *, "This is boundaryA" end subroutine boundaryA ! boundaryA的唯一标签函数 integer function tag_boundaryA() tag_boundaryA = 1 end function tag_boundaryA subroutine boundaryB() print *, "This is boundaryB" end subroutine boundaryB ! boundaryB的唯一标签函数 integer function tag_boundaryB() tag_boundaryB = 2 end function tag_boundaryB end module boundary_mod program test_proc_ptr use boundary_mod implicit none ! 关联过程指针的同时,关联对应的标签指针 bc => boundaryA bc_tag => tag_boundaryA ! 通过调用标签函数返回的唯一值来判断 if (bc_tag() == 1) then print *, "bc is associated with boundaryA" else if (bc_tag() == 2) then print *, "bc is associated with boundaryB" else print *, "bc is not associated" end if ! 切换关联对象 bc => boundaryB bc_tag => tag_boundaryB if (bc_tag() == 1) then print *, "bc is associated with boundaryA" else if (bc_tag() == 2) then print *, "bc is associated with boundaryB" else print *, "bc is not associated" end if end program test_proc_ptr
这个方法的核心是:每次绑定过程指针bc的时候,同时绑定对应的标签指针bc_tag,通过标签返回的唯一整数来区分不同的子程序,完全兼容旧版Fortran标准。
另外提一句:gfortran 4.8.2是2013年的老版本了,对Fortran 2003的支持并不完善,要是条件允许,升级到新一点的版本(比如10.x及以上)会省很多麻烦~
内容的提问来源于stack exchange,提问作者zljt3216
相关产品推荐
相关产品推荐

