William F Mitchell schrieb:
> Friedrich Hertweck wrote:
>
> > This is the important point: the result is a NEW array with the
> > desired shape; RESHAPE acts like an array constructor. It is NOT
> > another view of the source array. In the general case the new array
> > is quite different compared to the source.
>
> I agree with this statement, but ...
>
> > In this simple case (where the number and order of elements of the
> > RESHAPE result is exactly that of the source) it is conceivable that
> > an optimizing compiler might convey the address of the source to the
> > function, provided the dummy argument is defined as
> > integer, target, intent(in) :: R2(:,:)
> > Because R2 cannot be modified, no harm could be done, could it?
> > Well, I do not think this kind of optimization is permissible,
> > because it changes the semantics of the program (like, for instance,
> > -O3 with the IBM compiler, where sometimes a warning is issued to
> > this effect). And it is easy to overrule the INTENT(IN) specification:
> > just use RES2 to modify the array. It works on at least some systems!
>
> I don't think I agree with you here. I don't see why the optimization could
> not be done, as long as the dummy argument is intent(in). With intent(in) the
> compiler can assume the argument will not be changed. If the user overrules it
> as you suggest, then the program is not standard conforming.
I have not found any rule that prohibits this. In a pointer assignment definition
there
is no constraint to that effect, and in the F95SD in section 5.1.2.3 (INTENT
attribute)
there is even an inconsistency: there is the constraint that a dummy pointer must not
have
the INTENT attribute, and the next constraint lists as case (2) that a dummy argument
with the INTENT(IN) attribute shall not appear as the pointer-object of a
pointer-assignment-stmt. So the question is: what is standard-conforming?
(By the way, all eight systems mentioned compile such a code without complaint and
do change the INTENT(in) argument.)
The standard document says in 1.5 (Conformance):
A program is a standard-conforming program if it uses only those forms and
relationships
described herein and if the program has an interpretation according to this standard.
As far as I can see, the production of undefined pointers is standard-conforming,
because
it says: " ... if you do such and such, the pointer status becomes undefined ...".
>
> But your main point stands intact. The result of reshape is an expression, which
> will not exist after returning from the subroutine, and the pointer is in an
> undefined state. It's another instance of something that might just happen to
> work on some compilers, or some compilers at some optimization levels.
>
> > - should a compiler be able to check on this situation?
> > I should think yes, because all the information is there,
> > because a module procedure has an explicit interface. The
> > compiler could see that a pointer result of a function is
> > associated directly with a target dummy argument which is
> > an expression in the function invokation. This testing is
> > similar to what the compiler has to do with INTENT arguments.
>
> I think I disagree with this, too. From the explicit interface, the compiler
> does not know that the result is associated with the dummy argument, i.e.,
> it does not know about the statement res2=>r2
It is not only the interface: the function result is a pointer-assignment.
A function like that does NOT make sense if it returns an undefined pointer.
That should restrict permissible targets to objects that are in some sense
permanent: an allocate statement would be OK (it allocates memory on the heap),
or a pointer assignment to another object in principle outside the scope of
the function. A dummy argument (which of cause must have the TARGET attribute)
is also OK, provided it is associated with permanent storage. Here is an improved
version of the function RES2 which will NOT accept the result of the RESHAPE:
function ptr(a,n1,n2)
integer, pointer :: ptr(:,:)
integer :: n1, n2
integer, target, INTENT(INOUT) :: a(n1,n2)
ptr => a
end function
The INTENT(INOUT) makes sure that the actual argument a(n1,n2) cannot be an
expression (or, which is basically the same, an indexed array section).
When the actual argument corresponding to a(n1,n2) does not have the TARGET
attribute,
the function permits a pointer to be assigned to a non-target object, which moreover
violates the rule that a pointer shall only be assigned to a target of the same
type,
kind type parameters, and rank (sec. 7.5.2 - Pointer assignment).
I do not feel uncomfortable with this situation: it it just one more case of looking
at object
with a different view: EQUIVALENCE can be used (should NOT be of cause), within a
procedure the explicit-shape argument does it by sequence-association, and here we
have
the pointer which returns this view to the caller.
So I maintain my position that a good compiler should be able to check on these
things.
For instance a compiler does know if you invoke a subroutine, call sub(i*j+k), say,
where
the dummy argument is INTENT(OUT): it is a compile time error. When the module is
compiled, the dummy argument of the function evidently gets a tag that it must not be
an
expression, and this tag is known in the interface. A similar tag could be put on the
argument
of a if the function result pointsat it. So I still believe a compiler could do a
lot more analysis.
You may of cause argue that incorrect programs may well be standard conforming (which
is
of course true), but I am a believer in reliable software: any obvious errors
detected and any
warnings will help the user.
> > The following program works on all of the eight systems mentioned
> > above and does what was originally intended:
>
> Very interesting. Sequence association is more liberal than I thought. I
> thought that disagreement in rank was only allowed when the actual argument
> is an array element, to be backward compatible with common practice in FORTRAN 77
> programs, and that otherwise the mismatch was not standard conforming but happens
> to work under most compilers when there is no explicit interface, because of the
> way arguments are passed. 12.4.1.4 is worth a careful reading -- this legalizes
> a lot of code I thought was illegal (in a loose sense of the word "legal").
>
> > As already mentioned above, ptr(...) works on all of the eight systems
> > I have access to. I would be interested to learn about any system
> > where this simple mechanism does not work!
The problem here is that the standard wording is vague: the facility is supposed to
be
PROCESSOR DEPENDENT, so the user must check it. This is not completely satisfactory.
I don't know whether the compiler manufacturers have a document that tells what
PROCESSOR DEPENDENT features do on that processor. I have not seen any such
document, but the standard says in NOTE 1.1 of sec. 1.5:
"The processor should be accompanied by documentation that specifies the methods or
semantics of processor-dependent facilities". Should? Must?
>
> On Linux, your program works as expected with NAG, NASoftware, Absoft, Lahey,
> Fujitsu, PGI and PSR.
That is good to know (I am a LINUX fan myself, but so far have not tried this on
LINUX).
Regards,
Friedrich
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|