【问题标题】:Constant function pointer array in Fortran 2003Fortran 2003 中的常量函数指针数组
【发布时间】:2015-06-18 08:58:31
【问题描述】:

亲爱的 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

【问题讨论】:

    标签: fortran fortran2003 fortran2008


    【解决方案1】:

    Fortran 2008 允许将过程指针和过程指针组件初始化到过程目标(相对于NULL())。语法与其他初始化器一致。

    ! In the scope of the module.
    ...
    type(ptrWrap), parameter :: switcher(2) = [ptrWrap(func1), ptrWrap(func2)]
    ...
    

    【讨论】:

    • 这似乎正是我想要的。不幸的是,到目前为止,我拥有的所有编译器(intel15、nagfor 6.0、gfortran 5.0)都无法应对它。例如 NAG 抱怨Initialisation expression for SWITCHER is not constant。似乎,出于某些原因,他们不将模块过程识别为常量实体。
    • 请注意,这是 Fortran 2008 的一项功能。这些编译器目前都没有完全实现 Fortran 2008。几年后再试一次。
    【解决方案2】:

    我认为这是不允许的。根据我对 2008 年标准的阅读,parameterdata object 的一个属性,并且数据对象类不包括过程或过程指针。

    当你给它你的代码时,你的编译器告诉你什么?

    【讨论】:

    • 这也是我的阅读。如果将 PARAMETER 属性添加到 procedure-declaration-statement,gfortran 将发出错误 PARAMETER attribute conflicts with POINTER attribute
    • 已经尝试创建像procedure(funcInterface), pointer, parameter :: pFunc1 => func1 这样的常量过程指针,但我尝试过的所有编译器都失败了,这表明指针和参数属性之间存在冲突。但不确定为什么,因为它是一个常量,在运行期间不会改变,并且目标是一个在声明范围内的模块过程。
    • 我认为从根本上说你是在问一个物种的问题为什么语言 X 没有特征 Y? 即使可以提供一个权威和正确的答案你'仍然无法在 X 中做 Y。
    • 虽然过程指针不是数据对象,但具有过程指针组件的派生类型的对象是数据对象。
    • @HighPerformanceMark 你是对的,这更像是一个语言哲学问题。我想了解,如果有任何根本原因,为什么在 Fortran 中不允许这样做(例如,模块过程不被识别为常量实体)。在我看来,Fortran 是一种非常合乎逻辑和结果的语言,通常在被禁止的事情背后总有一个很好的解释。 :-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多