Search code examples
pointersfortranprocedure

How to judge if a fortran procedure pointer is associated with a specific subroutine


I want to know how to judge if a fortran procedure pointer is associated with a specific subroutine. The following a MWE (basically based on my previous question)

# module file
module boundary
implicit none

type bc_type
  procedure(boundary_type), pointer, nopass :: bc
  ! some other type-bound parameters
end type

abstract interface
  subroutine boundary_type(i)
    integer :: i
  end subroutine
end interface

contains

subroutine boundaryA(i)
integer :: i
  print*, 'Boundary A at ',i
end subroutine

subroutine boundaryB(i)
integer :: i
  print*, 'Boundary B at ',i
end subroutine

end module

# main file
program main
use boundary
implicit none
type(bc_type) :: a    

  a%bc => boundaryA

end program

I know that the function associated can be used to judge if a procedure pointer is associated, but how can I know which subroutine is it associated with? For here, if bc associated with boundaryA or boundaryB?

I tried

associated(a%bc, boundaryA)

The compiler (gfortran 4.8.2) gives an error that 'target' argument of 'associated' intrinsic at boundaryA must be the same type and kind as 'pointer'.

If the nopass attribute is removed, the compiler gives an error that argument 'i' of 'bc' with pass(i) at 'bc' must be of the derived type 'bc_type'.


Solution

  • Here's one way to do it.

    program main
    use boundary
    use, intrinsic :: iso_c_binding
    implicit none
    type(bc_type) :: a    
    
      a%bc => boundaryA
    
    if (same_proc(c_funloc(a%bc),c_funloc(boundaryA))) print *, "boundaryA"
    if (same_proc(c_funloc(a%bc),c_funloc(boundaryB))) print *, "boundaryB"
    
        contains
        function same_proc (a,b)
        use, intrinsic :: iso_c_binding
        logical same_proc
        type(c_funptr), intent(in) :: a,b
    
        same_proc = transfer(a,0_C_INTPTR_T) == transfer(b,0_C_INTPTR_T)
        end function same_proc
    
    
    end program