我正在尝试确定这两个选项中哪一个是最好的:
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
的调用是否符合指示的大小。但是,我不知道编译器是否可以在给定参数可分配时执行这些检查(如果此类分配取决于运行时确定的其他内容,则更是如此)。第二个需要显式接口(interface)并具有更多代码(检查),但似乎会捕获更多错误。
使用每一种的优点/缺点是什么?在什么情况下应该选择其中一种?
最佳答案
首先,一些术语。考虑声明为的虚拟参数
real :: a(n) ! An explicit shape array
real :: b(:) ! An assumed shape array
real, allocatable :: c(:) ! A deferred shape array (allocatable)
real, pointer :: d(:) ! A deferred shape array (pointer)
real :: e(*) ! An assumed size array
real :: f(..) ! An assumed rank array/scalar
我不会回答在给定情况下哪个更好,而只是简单地详细说明一些重要特征,将选择(如果有的话)留给程序员。粗略地(也是错误地),许多人将显式形状数组视为“Fortran 77”,将假定和延迟形状数组视为“Fortran 90+”。
假设的大小和假设的排名参数超出了本问题和答案的范围。
<小时/>形状:
- 显式形状数组的形状遵循其声明;
- 假定形状数组虚拟参数的形状是实际参数的形状;
- 延迟形状虚拟参数的形状可能是未定义的,在过程中或实际参数的形状中定义。
连续性:
- 显式形状数组是简单连续的;
- 假定形状数组虚拟参数的连续性与关联的实际参数的连续性相关;
- 延迟形状虚拟参数可能是实际参数,或者取决于过程的执行。
对实际论证的限制:
- 与显式形状数组关联的实际参数必须至少具有与虚拟参数一样多的元素;
- 与假定形状数组关联的实际参数本身不得采用假定大小;
- 与假定或延迟形状数组关联的实际参数必须与虚拟参数具有相同的等级。
调用范围内的接口(interface):
- 如果虚拟参数具有假定或延迟形状,则引用范围必须能够访问该过程的显式接口(interface)。
考虑真正的a(6)
。这可能是傻瓜们的真实论点
real b(3)
real c(2,3)
real d(:) ! With an explicit interface available
a(1::2)
可能与 b
关联,但由于 b
是连续的复制输入/复制输出涉及。与d
关联时不需要涉及复制入/复制出,但也可能涉及。
还有很多其他方面,但希望这是一个初步的高级介绍。
关于fortran - 将大小作为参数传递 VS 在 Fortran 过程中假定形状,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47913804/