5

Dear Fortran programmers,

does anybody know, whether it is possible to declare a constant (parameter) procedure pointer array in Fortran 2003 or above?

As given below, I have a switcher function, which calls different functions depending on an incoming integer argument. It uses an array of procedure pointers (wrapped in derived) types. This array has to be initialized via the init() routine during run time before it can be used. Is there any way, to initialize this array already during compilation and avoid the necessity of such an initialization routine? It could be then also defined as parameter, since it's value won't change during the run.

module testmod
  implicit none

  interface
    function funcInterface() result(res)
      integer :: res
    end function funcInterface
  end interface

  type :: ptrWrap
    procedure(funcInterface), nopass, pointer :: ptr
  end type ptrWrap

  type(ptrWrap) :: switcher(2)

contains

  subroutine init()
    switcher(1)%ptr => func1
    switcher(2)%ptr => func2
  end subroutine init

  function callFunc(ii) result(res)
    integer, intent(in) :: ii
    integer :: res
    res = switcher(ii)%ptr()
  end function callFunc

  function func1() result(res)
    integer :: res
    res = 1
  end function func1

  function func2() result(res)
    integer :: res
    res = 2
  end function func2

end module testmod


program test
  use testmod
  implicit none

  call init()  ! I'd like to get rid of this call.
  print *, callFunc(1)
  print *, callFunc(2)

end program test
Bálint Aradi
  • 3,754
  • 16
  • 22

2 Answers2

2

I don't think it is allowed. From my reading of the 2008 standard parameter is an attribute of a data object and the class of data objects does not include procedures or procedure pointers.

What did your compiler tell you when you fed it your code ?

High Performance Mark
  • 77,191
  • 7
  • 105
  • 161
  • That is my reading as well. gfortran will emit the error `PARAMETER attribute conflicts with POINTER attribute` if you add the `PARAMETER` attribute to the *procedure-declaration-statement* – casey Jun 18 '15 at 21:05
  • Already trying to create a constant procedure pointer like `procedure(funcInterface), pointer, parameter :: pFunc1 => func1` fails with all compiler I've tried, indicating a conflict between the pointer and the parameter attribute. But not sure, why, as it would be a constant, which does not change during the run and the target is a module procedure which is within the scope of the declaration. – Bálint Aradi Jun 19 '15 at 09:09
  • I think that fundamentally you're asking a question of the species *Why does language X not have feature Y ?* Even if it is possible to provide an authoritative and correct answer you're still left unable to do Y in X. – High Performance Mark Jun 19 '15 at 10:42
  • 1
    While procedure pointers are not data objects, an object of a derived type that has a procedure pointer component is a data object. – IanH Jun 20 '15 at 10:24
  • @HighPerformanceMark You are correct, it's more a language philisophical question. I'd like to understand, if there are any fundemental reasons, why it is not allowed in Fortran (e.g. module procedures not recognized as constant entities). Fortran is in my oppinion a very logical and consequent language, usually there is always a good explanation behind forbidden things. :-) – Bálint Aradi Jun 23 '15 at 13:24
2

Fortran 2008 permits initialization of procedure pointers and procedure pointer components to procedure targets (versus NULL()). The syntax is consistent with other initializers.

! In the scope of the module.
...
type(ptrWrap), parameter :: switcher(2) = [ptrWrap(func1), ptrWrap(func2)]
...
IanH
  • 21,026
  • 2
  • 37
  • 59
  • That seems to be exactly what I was looking for. Unfortunately, none of the compiler I have (intel15, nagfor 6.0, gfortran 5.0) is able to cope with it so far. For example NAG complains about `Initialisation expression for SWITCHER is not constant`. It seems, that they do not recognize the module procedures as constant entities for some reasons. – Bálint Aradi Jun 23 '15 at 13:20
  • Note it is a Fortran 2008 feature. None of those compilers currently fully implement Fortran 2008. Try again in a few years time. – IanH Jun 23 '15 at 20:43