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
Omar Awile
  • 140
  • 1
  • 6

1 Answers1

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.

  • 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? – Omar Awile Jul 08 '12 at 21:40
  • 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... – Omar Awile Jul 08 '12 at 21:48
  • 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. – Vladimir F Героям слава Jul 09 '12 at 07:23
  • OK, thanks! Then I guess there is no solution but the hack I proposed in the comment above. – Omar Awile Jul 09 '12 at 07:29