(j3.2006) FW: interp fodder from comp.lang.fortran
Lionel, Steve
steve.lionel
Thu Sep 3 14:54:07 EDT 2015
Let me try this one more time...
Steve
-----Original Message-----
From: Lionel, Steve
Sent: Thursday, September 3, 2015 9:43 AM
To: fortran standards email list for J3 <j3 at mailman.j3-fortran.org>
Subject: RE: (j3.2006) interp fodder from comp.lang.fortran
Ian Harvey posted a followup with some interesting observations. I haven't
given this sufficient thought, myself...
---
Today the standard pretty clearly says you either have intrinsic assignment,
or defined assignment. Defined assignment doesn't involve automatic
reallocation on assignment.
In some hypothetical future, I think you would have to think very carefully
about how this would all work and what it will achieve. The reallocation of
the left hand side to the shape of the right hand side would have to happen
*before* the elemental procedure could be invoked. That reallocation would
imply finalization and loss of the value of the left hand side in the
general case - the left hand side would be undefined prior to the call - it
would only make sense for the corresponding argument to be INTENT(OUT).
That slays a great deal of applications of defined assignment there and
then.
> The lack of the ideal could be worked around with a separate defined
assignment, but I cannot seem to convince the compiler to not use the
elemental subroutine. For example, with the following program:
>
> MODULE A_TEST_M
> TYPE :: A_TYPE
> INTEGER :: INT
> !
> CONTAINS
> !
> GENERIC :: ASSIGNMENT (=) => ASGN_A
> PROCEDURE, PRIVATE :: ASGN_A
> END TYPE
>
> INTERFACE ASSIGNMENT (=)
> MODULE PROCEDURE REALLOC_ASGN_A
> END INTERFACE ASSIGNMENT (=)
> CONTAINS
>
> SUBROUTINE REALLOC_ASGN_A (A, B)
> TYPE (A_TYPE), ALLOCATABLE, INTENT (INOUT) :: A(:)
> TYPE (A_TYPE), INTENT (IN) :: B(:)
> TYPE (A_TYPE), ALLOCATABLE :: TMP(:)
> !
> ALLOCATE (TMP(SIZE(B)))
> TMP(:)%INT = B(:)%INT
> CALL MOVE_ALLOC (TMP, A)
> END SUBROUTINE
>
> ELEMENTAL SUBROUTINE ASGN_A (A, B)
> CLASS (A_TYPE), INTENT (INOUT) :: A
> CLASS (A_TYPE), INTENT (IN) :: B
> !
> A%INT = 45
> END SUBROUTINE
> END MODULE A_TEST_M
> !
> PROGRAM ASGN_REALLOC_TEST
> USE A_TEST_M
> TYPE (A_TYPE), ALLOCATABLE :: A(:)
> !
> ALLOCATE (A(4))
> A(1:2)%INT = 7
> A(3:4)%INT = 13
> !
> A = A(1:2)
> !
> PRINT *, 'SIZE(A)', SIZE(A), 'A:', A
> END PROGRAM
>
> If I comment out the bound, defined assignment ASGN_A in the type
definition, then everything seems to work fine and REALLOC_ASGN_A is
utilized. If I do not, then the result is the same as before.
I think that's a compiler bug. Elemental procedures are only supposed to be
considered if there is no non-elemental procedure that matches on rank, and
that consideration covers the merged set of specific bindings and procedures
for the generic identifier associated with assignment.
(If the left hand side of your assignment was not allocatable, I would
expect an error message about an inappropriate actual argument for the
allocatable dummy.)
This does not address your specific query, and may not be a relevant
approach depending on the specifics of what you want to do in the assignment
procedures themselves, but my default approach here would be to not use
defined assignment at all, but author functions that accomplished the
necessary transformation of the original right hand side expression to
something suitable for intrinsic assignment to the left hand side.
On classic case where defined assignment is required is for some sort of
reference counting approach. But reallocation on assignment kills that
because of the effective INTENT(OUT) of the left hand side discussed above,
so that can't be what you are doing...
-----Original Message-----
From: j3-bounces at mailman.j3-fortran.org
[mailto:j3-bounces at mailman.j3-fortran.org] On Behalf Of Robert Corbett
Sent: Thursday, September 3, 2015 6:45 AM
To: j3 <j3 at j3-fortran.org>
Subject: (j3.2006) interp fodder from comp.lang.fortran
A post to c.l.f. by Andrew Baldwin shows what appears to be a flaw in the
standard regarding assignments to allocatable variables. Consider the
assignment statement
A = B
where A is an allocatable array variable and B is an array expression of the
same rank, type, and kind.
Suppose there is an elemental subroutine for the type and kind of A and B
and a generic interface that specifies ASSIGNMENT(=) that includes the
subroutine as a specific subroutine. Then if A and B have the same shape,
the assignment is done as a defined assignment, but if A and B have
different shapes, the assignment is done as an intrinsic assignment that
deallocates and then allocates A.
Clause 7.2.1.4 of the Fortran 2008 standard sets out the conditions for when
a defined assignment is performed. The key part of the clause for this
example is item (5) which states
(b) the subroutines is elemental, x[1] and
x[2] are conformable, and there is no
other subroutine that defines the
assignment.
Two arrays are conformable if they have the same shape. Therefore, whether
the assignment is done as a defined assignment or an intrinsic assignment
depends on whether A and B have the same shape.
The problem was introduced in the Fortran 2003 standard. In Fortran 90 and
Fortran 95, the array variable A was required to be allocated and the shapes
of A and B were required to be the same for both defined and intrinsic
assignments.
Fortran 2003 relaxed the restrictions for intrinsic assignments, but not for
defined assignments. The obvious fix for the problem is to relax the
restrictions for defined assignments as well.
Robert Corbett
_______________________________________________
J3 mailing list
J3 at mailman.j3-fortran.org
http://mailman.j3-fortran.org/mailman/listinfo/j3
More information about the J3
mailing list