5

I am trying to write a generic type-bound procedure that takes different callback functions as parameters. When compiling following code (with ifort 12.1.3) I get the warning below:

module test

type :: a_type
  contains
  procedure :: t_s => at_s
  procedure :: t_d => at_d
  generic :: t => t_s,t_d
end type a_type

abstract interface
  integer function cb_s(arg)
  real(4) :: arg
  end function cb_s

  integer function cb_d(arg)
  real(8) :: arg
  end function cb_d
end interface

contains

subroutine at_s(this,cb)
  class(a_type) :: this
  procedure(cb_s) :: cb 
end subroutine

subroutine at_d(this,cb)
  class(a_type) :: this
  procedure(cb_d) :: cb 
end subroutine

end module test

The warning:

compileme.f(27): warning #8449: The type/rank/keyword signature for this specific
procedure matches another specific procedure that shares the same generic
binding name.   [AT_D]

It seems like the compiler is not differentiating between different function interfaces when used as procedure arguments...

My question is: Why aren't those types checked and what is the correct, clean way to write generic type-bound procedures with procedures or procedure pointers as arguments?

Possible solution

As Vladimir F pointed out, only the callback function's return arguments are type checked. In my case it is OK to then just slightly change the functions' interfaces:

abstract interface
  real(4) function cb_s(arg)
  real(4) :: arg
  end function cb_s

  real(8) function cb_d(arg)
  real(8) :: arg
  end function cb_d
end interface

1 Answer 1

4

The compiler is right, because Fortran 2008's 12.4.3.4.5 Restrictions on generic declarations has

Two dummy arguments are distinguishable if - one is a procedure and the other is a data object, - they are both data objects or known to be functions, and neither is TKR compatible with the other, - one has the ALLOCATABLE attribute and the other has the POINTER attribute, or - one is a function with nonzero rank and the other is not known to be a function.

It means that both your functions are integer functions so they are not distinguishable.

Sign up to request clarification or add additional context in comments.

4 Comments

Yes, you're right of course, I made a mistake when writing the title, obviously those are not procedure pointers. And yes, they are both integer functions, but their arguments are once a real(4) and once a real(8). I thought different real kinds are distinguishable? Also, how would you go about supporting both single and double precision function dummy arguments in one generic type bound procedure?
OK, I tried two more things, to better understand this: (1) I replaced the integer return values of cb_s and cb_d by real(4) and real(8) respectively, and even though this changes the semantics, it works. So does Fortran only check the return value of dummy argument functions? (2) I replaced the functions by subroutines taking an additional parameter for the return value and declared the intent of the arguments - this again failed with the same warning as before...
Yes, only return values are checked. You can also distinguish functions from subroutines. If dummy arguments could be distinguishable according to their dummy arguments, it could lead to a long, perhaps infinite, chain, probably across many modules.
OK, thanks! Then I guess there is no solution but the hack I proposed in the comment above.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.