传递大小作为参数 VS 在 Fortran 程序中假设形状

Passing size as argument VS assuming shape in Fortran procedures

我正在尝试确定这两个选项中哪一个是最好的:

subroutine sqtrace( Msize, Matrix, Value )
  integer, intent(in)  :: Msize
  real*8,  intent(in)  :: Matrix(Msize, Msize)
  real*8,  intent(out) :: Value

  [instructions...]

end subroutine sqtrace

VS

subroutine sqtrace( Matrix, Value )
  real*8,  intent(in)  :: Matrix(:,:)
  real*8,  intent(out) :: Value

  if ( size(Matrix,1) /= size(Matrix,2) ) then
    [error case instructions]
  end if

  [instructions...]

end subroutine sqtrace

我知道当你编译时有警告,第一种情况应该在编译时自动检查对 sqtrace 的调用是否符合指示的大小。但是,我不知道编译器是否可以在给定参数可分配时执行这些检查,例如(如果这种分配取决于运行时确定的其他事情,则更是如此)。第二个需要一个显式接口并且有更多代码(检查),但似乎会捕获更多错误。

使用每一种的 advantages/disadvantages 是什么?在哪些情况下应该使用一种而不是另一种?

首先,一些术语。考虑声明为

的虚拟参数
real :: a(n)                ! An explicit shape array
real :: b(:)                ! An assumed shape array
real, allocatable :: c(:)   ! A deferred shape array
real :: d(*)                ! An assumed size array

(延迟形状数组也可以是指针而不是可分配的)。

我不会回答在给定情况下哪个更好,但会简单地详细说明一些重要的特性,让程序员有选择的地方。粗略地说,许多人将显式形状数组视为 "Fortran 77" 并将假定形状数组视为 "Fortran 90+".


形状:

  • 显式形状数组的形状遵循其声明;
  • 假定形状数组伪参数的形状是实际参数的形状;
  • 延迟形状虚拟参数的形状可能未定义,在过程中或实际参数的形状中定义。

连续性:

  • 显式形状数组只是连续的;
  • 假定形状数组虚拟参数的连续性与关联实际参数的连续性相关;
  • 延迟形状伪参数可能是实际参数的参数,或者取决于过程的执行。

实参限制:

  • 与显式形状数组相关联的实参必须至少具有与伪参一样多的元素;
  • 与假定形状数组相关联的实际参数本身不得为假定大小;
  • 与假定或延迟形状数组关联的实际参数必须与虚拟参数具有相同的等级。

调用范围内的接口:

  • 如果伪参数是假定的或延迟的形状,则引用范围必须具有可访问的过程的显式接口。

考虑 real a(6)。这可能是假人的真实论据

real b(3)
real c(2,3)
real d(:)   ! With an explicit interface available

a(1::2) 可能与 b 相关联,但由于 b 是连续的 copy-in/copy-out 将涉及。 Copy-in/copy-out 与 d 关联时不需要参与,但可能会。

还有很多其他方面,但希望这是一个初步的高级介绍。