> I have a situation where (in multiple places) I need to make an alias
> for a specific array section. For example,
>
> x => a(N,:)
>
> where N is a parameter. However for reasons I won't go into, I'd
> prefer to hide the specifics of the array section, using instead
> one of the following alternatives:
>
> (a) x => select_x (a); with
>
> function select_x (a) result (x)
> real, dimension(:,:), target :: a
> real, dimension(:), pointer :: x
> x => a(N,:)
> end function select_x
>
> (b) call select_x (a, x); with
>
> subroutine select_x (a, x)
> real, dimension(:,:), target :: a
> real, dimension(:), pointer :: x
> x => a(N,:)
> end subroutine select_x
>
> Are these standard conforming? I strongly suspect (a) isn't, though
> I haven't been able to confirm this in any of my F90 references.
> (I get incorrect results with one compiler that I have great confidence
> in, but correct results with another.) I'm fairly certain (b) is OK,
> but here again I may not be reading my F90 references correctly.
> Any page references to Fortran 90 Explained or F90 Handbook would be
> greatly appreciated.
This was a rare case where an interpretation actually altered a rule
that was unambiguously stated in the Fortran 90 standard. The original
rule makes your code processor-dependent, because copy-in copy-out was
permitted for any dummy argument with the TARGET attribute. It was decided
that this was too surprising, and indeed Mike and I made the mistake
in our big pointer example at the back of our book.
If you can make your array be a pointer, all will be well (with both the
old interpretation and the new). This is what we have done with our example
(see the argument root of subroutine look, about half-way down page 305
of F90/95 Explained or page 291 of F90/95 Explained). We intend to change
this back when we are reasonably sure that compilers that correctly
implement the old rule are no longer in use.
This is what we now say (Section 5.7.3)
In most circumstances, an implementation is permitted to make a copy of
an actual argument on entry to a procedure and copy it back on return.
This may be desirable on efficiency grounds, particularly when the
actual argument is not held in contiguous storage. In any case, if a
dummy argument has neither the TARGET nor POINTER attribute, any
pointers associated with the actual argument do not become associated
with the corresponding dummy argument but remain associated with the
actual argument.
However, copy in~/~copy out is not allowed when
i) a dummy argument has the TARGET attribute and
is either scalar or is an assumed-shaped array, and
ii) the actual argument is a target other than an array section with a
vector subscript.
In this case, the dummy and actual arguments must have the same shape,
any pointer associated with the actual argument becomes associated with
the dummy argument on invocation, and any pointer associated with the
dummy argument on return remains associated with the actual argument.
When a dummy argument has the TARGET attribute, but the actual argument
is not a target or is an array section with a vector subscript, any
pointer associated with the dummy argument obviously becomes undefined
on return.
In other cases where the dummy argument has the TARGET attribute,
whether copy in / copy out occurs is processor dependent. No reliance
should be placed on the pointer associations with such an argument
after the invocation.
I hope this helps. I can point you to the wording in the standard if
you wish.
John Reid.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|