问题
I'm trying to decide which one of these two options would be the best:
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
I understand that when you compile with warnings, the first case should automatically check at compile time if calls to sqtrace
comply with the size indicated. However, I don't know if the compiler can perform those checks when the given arguments are allocatable, for example (more so if such allocation depends on other things that are determined at runtime). The second one requires an explicit interface and has more code (the checks), but would seem to catch more errors.
Which are the advantages/disadvantages of using each and in which cases should one go with one over the other?
回答1:
First, some terminology. Consider the dummy arguments declared as
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
(a deferred shape array may also be a pointer rather than an allocatable).
I won't answer in terms of which is better in a given situation, but will simply detail some of the important characeristics leaving choice, where there is one, to the programmer. Crudely, many view explicit shape arrays as "Fortran 77" and assumed shape arrays as "Fortran 90+".
Shape:
- the shape of an explicit shape array follows its declaration;
- the shape of an assumed shape array dummy argument is that of the actual argument;
- the shape of a deferred shape dummy argument may be undefined, becoming defined in the procedure, or that of the actual argument.
Contiguousness:
- an explicit shape array is simply contiguous;
- an assumed shape array dummy argument's contiguousness relates to that of the associated actual argument;
- a deferred shape dummy argument may be that of the actual argument, or depending on the procedure's execution.
Restrictions on actual argument:
- an actual argument associated with an explicit shape array must have at least as many elements as the dummy argument;
- an actual argument associated with an assumed shape array must not itself be assumed size;
- an actual argument associated with an assumed or deferred shape array must be of the same rank as the dummy argument.
Interfaces in the calling scope:
- if a dummy argument is of assumed or deferred shape, the referencing scope must have accessible an explicit interface for the procedure.
Consider real a(6)
. This may be an actual argument to the dummies
real b(3)
real c(2,3)
real d(:) ! With an explicit interface available
a(1::2)
may be associated with b
but as b
is contiguous copy-in/copy-out will be involved. Copy-in/copy-out needn't be involved when associated with d
, but it may be.
There are plenty of other aspects, but hopefully this is an initial high-level introduction.
来源:https://stackoverflow.com/questions/47913804/passing-size-as-argument-vs-assuming-shape-in-fortran-procedures