如何让通用子例程在具有假定大小数组的 Fortran 中工作

jan*_*195 4 arrays generic-programming fortran90

我有一个接口块来定义一个通用子例程,该子例程有一个假定大小的数组作为虚拟参数(以便能够作用于传递数组的“中间”,如 C 指针),但它无法编译。这是一个简单的例子:

module foo

  interface sub
     module procedure isub
     module procedure dsub
  end interface

  contains

  subroutine isub(a,n)
    integer, intent(in) :: a(*), n
    integer :: i
    print*, 'isub'
    do i=1,n
     print*, a(i)
    enddo
  end subroutine isub

  subroutine dsub(a)
    real(8), intent(in) :: a(*)
    integer, intent(in) :: n
    integer :: i
    print*, 'dsub'
    do i=1,n
     print*, a(i)
    enddo
  end subroutine dsub

end module foo

program test

  use foo

  implicit none

  integer :: ai(4)
  real(8) :: ad(4)

  ai=(/1,2,3,4/)
  ad=(/1.,2.,3.,4./)

  call sub(ai,3)
  call sub(ad,3)

  call isub(ai(2),3)
  !call sub(ai(2),3)

end program test
Run Code Online (Sandbox Code Playgroud)

注释行无法编译,而直接调用子例程时可以call isub(ai(2),3)(使用 gfortran 和 ifort 测试)。为什么以及是否可以使用它call sub(ai(2),3)

编辑:使用 ifort,它说:

$ ifort overload.f90
overload.f90(37): error #6285: There is no matching specific subroutine for this generic subroutine call.   [SUB]
  call sub(ai(2),3)
-------^
compilation aborted for overload.f90 (code 1)
Run Code Online (Sandbox Code Playgroud)

谢谢

Ale*_*ogt 6

您正在将标量传递给需要数组的函数。尝试

call sub(ai(2:2))
Run Code Online (Sandbox Code Playgroud)

它传递一个长度为 1 的数组。我想知道为什么call isub(ai(2))会被接受,但是......

回答您的新问题(部分在评论中):

如果您将自己限制为连续数组,则可以使用延迟形状数组call sub(ai(2:4)) 而不会损失性能:

subroutine isub(a)
  integer,intent(in) :: a(:)
  integer            :: i

  print*, 'isub'
  do i=1,size(a)
    print*, a(i)
  enddo
end subroutine isub
Run Code Online (Sandbox Code Playgroud)

没有使用ifort或创建临时数组gfortran。您可以使用以下方法检查这一点:

  • ifort -check arg_temp_created

  • gfortran -Warray-temporaries