From <@iec.co.uk:malcolm@num-alg-grp.co.uk>  Fri Sep 15 11:59:31 1995
Received: from sun2.nsfnet-relay.ac.uk (sun2.nsfnet-relay.ac.uk [128.86.8.45]) by dkuug.dk (8.6.12/8.6.12) with SMTP id LAA09505 for <sc22wg5@dkuug.dk>; Fri, 15 Sep 1995 11:59:21 +0200
Via: uk.co.iec; Fri, 15 Sep 1995 10:58:47 +0100
Received: from mars.nag.co.uk by nags2.nag.co.uk (4.1/UK-2.1) id AA15679;
          Fri, 15 Sep 95 11:02:09 BST
From: Malcolm Cohen <malcolm@num-alg-grp.co.uk>
Message-Id: <4888.199509150953@mars.nag.co.uk>
Received: by mars.nag.co.uk (5.65c/UK-2.1) id AA04888;
          Fri, 15 Sep 1995 10:53:17 +0100
Subject: Interp 179 - DO variable with POINTER attribute
To: sc22wg5 <sc22wg5@dkuug.dk>
Date: Fri, 15 Sep 95 10:53:10 MET DST

This interpretation is all wrong.  It is attempting to remove a facility which
has been in the language for the last 4 years.  There is no problem with the
facility or its description in the standard (*).  It is far too late to be
redesigning Fortran 90.

(*) Or rather, no problem which is not a problem with all POINTER variables!
    But I do not think it would be acceptable to delete all POINTER variables
    from the language; some users might object.

> NUMBER: 000179
> TITLE: DO variable with POINTER attribute
> KEYWORDS: DO variable, POINTER attribute
> DEFECT TYPE: Erratum
> STATUS: X3J3 draft response
> 
> QUESTION: The first constraint following rule R822 states:
> 
>  "Constraint:  The <do-variable> must be a named scalar variable of type
>                integer, default real, or double precision real."
> 
> The definition of loop initiation (8.1.4.4.1) states:
> 
>   "(2) The DO variable becomes defined with the value of the initial
>        parameter <m>1."
> 
> The definition of the execution cycle of a DO loop (8.1.4.4.2) states:
> 
>   "(3) ... The DO variable, if any, is incremented by the value of the
>        incrementation parameter <m>3."
> 
> Consider the following program:
> 
>       INTEGER, POINTER  :: PTR
>       INTEGER, TARGET   :: LCV
> 
>       PTR => LCV
> 
>       DO PTR = 1, 3
>         PRINT *, LCV
>       END DO
> 
>       END
> 
> Note that the DO variable has the POINTER attribute.  The POINTER attribute does
> not seem to be prohibited for the DO variable, but when the DO variable has the
> POINTER attribute, it is unclear as to whether the DO variable is the pointer or
> the target of the pointer.  That is, it is unclear as to whether the pointer or
> the target is to be "defined" (8.1.4.4.1) or incremented (8.1.4.4.2).

The above statements are wrong.  The standard is perfectly clear - "defining" a
pointer variable "defines" the target.

Consider the statement
  PTR = 1
This "defines" the pointer (the language used by the standard!!!).  The
standard is completely in agreement with itself in thinking that the initial
"defining" in
  DO PTR = 1, 10
is exactly the same as the "defining" of the variable in
  PTR = 1

To go on, "incrementing" the pointer variable in
  PTR = PTR + 1
is ***EXACTLY THE SAME*** as what happens in each iteration of
  DO PTR = 1,10

I note that the only possible confusion arise with certain FORTRAN 77
extensions, also (unfortunately) called POINTER.  In the extension to which I
am referring,
  PTR = PTR + 1
does pointer arithmetic, instead of adding 1 to the value of the target!  So if
we are to delete DO POINTER variables (because of confusion with C or with a
certain F77 POINTER extension) we have to forbid "PTR = PTR + 1" as well.

> Also consider the following modification of the above program:
> 
>       INTEGER, POINTER  :: PTR
>       INTEGER, TARGET   :: LCV1, LCV2
> 
>       LCV1 = 1
>       LCV2 = 4
> 
>       PTR => LCV1
> 
>       DO PTR = 1, 3
>         IF (...) PTR => LCV2    ! An alternate EXIT form?
>       END DO
> 
>       END
> 
> The standard does not seem to address what happens when the DO variable is
> switched to a different variable while the loop is active.

Yes the standard DOES say exactly what the situation is: it says that the
program in NOT standard-conforming.  See page [103:14-15], I quote:
  "Except for the incrementation of the DO variable that occurs in step (3),
   the DO variable must neither be redefined nor become undefined while the
   DO construct is active."

Now look at "14.7.5 Events that cause variables to become defined", event (18),
[251:9-10], I quote:
  "(18) Execution of a pointer assignment statement that associates a pointer
        with a target that is defined causes the pointer to become defined."

So "PTR => LCV2" defines PTR, the active DO variable, so is illegal.

To consider the other interesting cases, see "14.7.6 Events that cause
variables to become undefined", [252:32-33], I quote:
  "(15) When the association status of a pointer becomes undefined or
        dissassociated (6.3), the pointer becomes undefined."

So it is illegal to DEALLLOCATE or NULLIFY the DO variable, and it is also
illegal to DEALLOCATE the target out from underneath it because that would also
cause it to become undefined.

> Did the standard mean to allow a DO variable to have the POINTER attribute?
> 
> 
> ANSWER:  No.  This oversight has been remedied by an edit.

The standard allows a POINTER variable to appear anywhere in an executable
statement where its target may appear (e.g. in an expression, on the left-hand
side of an assignment statement, as an actual argument).  To exclude one case
in particular would have made the language unnecessarily irregular, therefore
it is clear that the standard DID mean that it was possible for a DO variable
to have the POINTER attribute.

> Discussion: The description of the iterative form of the DO loop was essentially
> carried forward from the previous standard.  It was an oversight to not prohibit
> the DO variable from having the POINTER attribute.  Prohibiting the POINTER
> attribute prevents the confusion that can arise as demonstrated by the example
> programs given above.

There is no confusion in the standard about what the examples mean.  Indeed,
the only people who are confused about what
  INTEGER, TARGET :: target(10) = (/ (i,i=1,10) /)
  INTEGER, POINTER :: ptr
  ptr => target(1)
  DO ptr=1,10
    PRINT *,ptr
  END DO
are the same people who are confused by
  INTEGER, TARGET :: target(10) = (/ (i,i=1,10) /)
  INTEGER, POINTER :: ptr
  ptr => target(1)
  ptr = 1
  DO WHILE (ptr<=10)
    PRINT *,ptr
    ptr = ptr + 1     ! In Fortran 90, this is NOT pointer arithmetic !
  END DO

> EDITS:

None are required.

It is FAR FAR FAR TOO LATE to be deciding that some feature in the standard
might be "bad programming practice" or "confusing if you used another language
where similar syntax had different semantics".

There are PLENTY of pieces of Fortran language which can be misused or abused.
Just ripping out facilities which are in current use (yes, I know people who
use this!) is unacceptable.

-- 
...........................Malcolm Cohen, NAG Ltd., Oxford, U.K.
                           (malcolm@nag.co.uk)

