2

根据对象,我正在努力理解返回可分配数组的函数背后的逻辑。我喜欢这种结构,因为与子例程相比它更清晰,而且 fortran 中的纯函数是编写干净的函数式编程代码的绝佳方式。

假设我必须编写一个简单的函数,返回一个具有任意边界的索引数组,例如在这个程序中:

program test_allocatable_functionReturn
      implicit none

      integer, allocatable :: fun(:),sub(:),noa(:)
      integer, parameter :: low = -4
      integer, parameter :: hi  = 3

      call testsub(sub,low,hi)
      fun = testfun(low,hi)
      noa = testfun_noalloc(low,hi)

      print '(4(a,i3),a)', 'testsub:  lbound=',lbound(sub),'(expected = ',low,'), ubound=',ubound(sub),'(expected = ',hi,')'
      print '(4(a,i3),a)', 'testfun:  lbound=',lbound(fun),'(expected = ',low,'), ubound=',ubound(fun),'(expected = ',hi,')'
      print '(4(a,i3),a)', 'no alloc: lbound=',lbound(noa),'(expected = ',low,'), ubound=',ubound(noa),'(expected = ',hi,')'


      contains
             pure function testfun_noalloc(low,hi) result(array)
                integer, intent(in) :: low,hi
                integer :: array(low:hi)
                integer :: i
                 forall(i=low:hi) array(i) = i
             end function testfun_noalloc


             pure function testfun(low,hi) result(array)
                integer, allocatable :: array(:)
                integer, intent(in) :: low,hi
                integer :: i
                 allocate(array(low:hi))
                 forall(i=low:hi) array(i) = i
             end function testfun


             pure subroutine testsub(array,low,hi)
                integer, intent(out), allocatable :: array(:)
                integer, intent(in) :: low,hi
                integer :: i
                 allocate(array(low:hi))
                 forall(i=low:hi) array(i) = i
             end subroutine testsub

end program

我通过三种方式实现了它:

  • 返回可分配数组的函数 ( testfun)
  • 子程序 ( testsub)
  • 返回静态数组的函数 ( testfun_noalloc)

该子例程对返回数组进行操作,并正确分配它。(-4:3)在示例中,应返回一个大小合适的数组。在任一实现中,该函数都返回一个(1:hi-low+1)-sized 数组:

testsub:  lbound= -4(expected =  -4), ubound=  3(expected =   3)
testfun:  lbound=  1(expected =  -4), ubound=  8(expected =   3)
no alloc: lbound=  1(expected =  -4), ubound=  8(expected =   3)

为什么会这样?我得到这样一个事实,即在将函数返回值分配给我的 LHS 数组时,fortran 可能会重新分配数组,但即便如此,为什么它没有分配正确的边界?我知道在将静态数组传递给具有 f2003 风格的 lhs 重新分配的可分配对象时可能会发生这种情况,但是以可分配数组作为输入,我希望保留边界信息。我在这里错过了什么吗?顺便说一句,这个例子是用 gfortran 9.2.0 编译的。

谢谢,费德里科

4

0 回答 0