Постоянный массив указателей на функцию в Fortran 2003

Уважаемые программисты Fortran!

кто-нибудь знает, можно ли объявить массив указателей процедур констант (параметров) в Fortran 2003 или выше?

Как указано ниже, у меня есть функция переключателя, которая вызывает разные функции в зависимости от входящего целочисленного аргумента. Он использует массив указателей процедур (заключенных в производные) типов. Этот массив должен быть инициализирован с помощью процедуры init() во время времени выполнения, прежде чем его можно будет использовать. Есть ли способ инициализировать этот массив уже во время компиляции и избежать необходимости такой процедуры инициализации? Тогда его также можно было бы определить как parameter, поскольку его значение не изменится во время выполнения.

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

person Bálint Aradi    schedule 18.06.2015    source источник


Ответы (2)


Fortran 2008 разрешает инициализацию указателей процедур и компонентов указателей процедур для целей процедуры (по сравнению с NULL()). Синтаксис соответствует другим инициализаторам.

! In the scope of the module.
...
type(ptrWrap), parameter :: switcher(2) = [ptrWrap(func1), ptrWrap(func2)]
...
person IanH    schedule 20.06.2015
comment
Кажется, это именно то, что я искал. К сожалению, ни один из имеющихся у меня компиляторов (intel15, nagfor 6.0, gfortran 5.0) пока с этим не справляется. Например NAG жалуется на Initialisation expression for SWITCHER is not constant. Похоже, что они по каким-то причинам не признают процедуры модуля как константы. - person Bálint Aradi; 23.06.2015
comment
Обратите внимание, что это функция Fortran 2008. Ни один из этих компиляторов в настоящее время полностью не реализует Fortran 2008. Повторите попытку через несколько лет. - person IanH; 23.06.2015

Я не думаю, что это разрешено. Насколько я знаю, стандарт 2008 г. parameter является атрибутом data object, а класс объектов данных не включает процедуры или указатели на процедуры.

Что ваш компилятор сказал вам, когда вы загрузили ему свой код?

person High Performance Mark    schedule 18.06.2015
comment
Это я тоже читаю. gfortran выдаст ошибку PARAMETER attribute conflicts with POINTER attribute, если вы добавите атрибут PARAMETER в инструкцию-декларации-процедуры - person casey; 19.06.2015
comment
Уже попытка создать постоянный указатель на процедуру, например procedure(funcInterface), pointer, parameter :: pFunc1 => func1, терпит неудачу со всеми компиляторами, которые я пробовал, что указывает на конфликт между указателем и атрибутом параметра. Но не уверен, почему, поскольку это будет константа, которая не изменяется во время выполнения, а целью является процедура модуля, которая находится в рамках объявления. - person Bálint Aradi; 19.06.2015
comment
Я думаю, что, по сути, вы задаете вопрос о расе Почему язык X не имеет функции Y? Даже если можно дать авторитетный и правильный ответ, вы все равно не сможете ответить Y в X. - person High Performance Mark; 19.06.2015
comment
Хотя указатели процедур не являются объектами данных, объект производного типа, который имеет компонент указателя процедуры, является объектом данных. - person IanH; 20.06.2015
comment
@HighPerformanceMark Вы правы, это скорее языковой философский вопрос. Я хотел бы понять, если есть какие-то фундаментальные причины, почему это не разрешено в Фортране (например, процедуры модуля не распознаются как постоянные объекты). На мой взгляд, Фортран - это очень логичный и последовательный язык, обычно за запретными вещами всегда есть хорошее объяснение. :-) - person Bálint Aradi; 23.06.2015