Re: Scope of implied-do index



Brooks Moses wrote:

Steven G. Kargl wrote:
(snip)

integer i
real x(10)
do i = 1, 10
x = (/ (i, i=1, 10) /)
end do

I spent about 15 minutes tracking down why that was illegal, and then came across section 14.1.3, which caused me to change my opinion and consider it to be legal:

Well, the 'loop' is actually done at compile time, or at least it
seems that way to me. That is a little more obvious for DATA, which
tends to generate an initialized static array. If not, it at least
generates the data that will be used to initialize the array. The
array constructor could be considered to generate an unnamed static
array at compile time.

"The name of a variable that appears as the DO variable of an implied-DO in a DATA statement or an array constructor has the scope of the implied-DO list. It is a scalar variable that has the type and type parameters that it would have if it were the name of a variable in the scoping unit that includes the DATA statement or array constructor, and this type shall be integer type."

It goes on to discuss the names of variables that are indices in FORALL statements in much the same way, and for those explicitly notes that they effectively mask the corresponding variable from the outer scoping unit rather than accessing it -- i.e. FORALL(i=1:10) x(i)=i would be legal there.

This isn't quite so obvious, as the assignments are actually
done at run time. The fact that they can be done in any order, and
that many to one assignments are not allowed, at least allows for
implementations where i is not a run time variable. On a vector
machine, it might be done as an assignment of a vector register.

From this I conclude that not only is your code legal, but the following (where i is an array in the outer scope, but a scalar within the construct) is also legal:

integer i(2,0:3,5)
real x(10)
x = (/ (i, i=1, 10) /)

Only the type and type parameters are used. The type parameter for INTEGER seems to be KIND, so it would seem that arrays are fine.

Note, though, that this does _not_ apply to implied-do loops in input/output statements! Those appear to be treated differently, and are not limited in scope. Aside from the fact that they're not included in the above quote, consider section 14.7.5 (Events that cause variables to become defined), which includes "Beginning of execution of the action specified by an implied-DO list in an input/output statement causes the implied-DO variable to become defined." -- input/output implied-DO loops are the only ones mentioned here. Also, section 9.4.2 requires that the variable for an i/o implied-do be a scalar variable; this restriction is not there for array-constructor or data implied-do loops.

This might be partly history. Implied-DO is required to do the operations in order. It is not required to actually modify the
variable of the same name in the outer scope, but as far as I know
it is allowed to modify it. I have known them be be implemented
as either loops in the compiled code or in the I/O library routines.

Similarly, the F2003 standard's section 16.5.7 (things you can't do with variables you aren't allowed to define or undefine, like INTENT(IN) arguments) specifically mentions "A do-variable in a do-stmt or io-implied-do", but not in implied-do constructs in array constructors or DATA statements.

Since implied-DO goes back at least to Fortran 66, this restriction
makes some sense based on the way compilers might implement it.

An additional complication, though, is that the text for array-constructor implied-do loops (section 4.5) states that nested implied-DO loops in an array constructor shall not use the same variable (by which I presume it means "the same variable name".) So they can't completely ignore _all_ outer context.

I suppose for something like

x=(/ ((1, I=1,10), I=1,10) /)

where the compiled value has no dependence on the loop variable.
Also, I don't see that restriction on DATA statements.

The text for input/output implied-do loops is similar, but includes the additional requirement that the variables in nested input/output implied-do loops shall not be associated -- which distinction makes sense with the fact that their scope is beyond that of the implied-do loop; the association would be irrelevant if they're not really the same variable as the one in the outer context.

My understanding is that for I/O implied DO the implementation is allowed to use the actual variable, but it is not required.

Thus, I conclude that your code sample and mine are legal, but were you to replace the array constructor in either of those with a write statement containing an implied-do, they would then be illegal.

I agree.

I further conclude that this distinction between types of implied-do loops and different rules for them is an extremely fine hair for the standard to be splitting, and I wish to register my sense of "Eeew!" at it!

It doesn't seem so fine to me. I think if I/O implied DO was added at
the same time as the others, it might have been done the same way.

If it had been my choice, I probably would have done FORALL more like
I/O implied DO, though.

Also, even though it is allowed it is probably less confusing
to the reader not to use the same variable.

-- glen

.



Relevant Pages

  • Re: Scope of implied-do index
    ... of an implied-do is limited to the implied-do. ... "The name of a variable that appears as the DO variable of an implied-DO in a DATA statement or an array constructor has the scope of the implied-DO list. ... section 9.4.2 requires that the variable for an i/o implied-do be a scalar variable; this restriction is not there for array-constructor or data implied-do loops. ... The text for input/output implied-do loops is similar, but includes the additional requirement that the variables in nested input/output implied-do loops shall not be associated -- which distinction makes sense with the fact that their scope is beyond that of the implied-do loop; the association would be irrelevant if they're not really the same variable as the one in the outer context. ...
    (comp.lang.fortran)
  • Re: NAG, Sun, Compaq possible f95 bug
    ... > implied-DO in a DATA statement or an array constructor has the ... This also seems to imply that default implicit typing is in effect, ...
    (comp.lang.fortran)
  • Re: Scope of implied-do index
    ... in a DATA statement or an array constructor has the scope of the implied-DO list. ... It is a scalar variable that has the type and type parameters that it would have if it were the name of a variable in the scoping unit that includes the DATA statement or array constructor, and this type shall be integer type." ...
    (comp.lang.fortran)
  • Re: Scope of implied-do index
    ... of an implied-do is limited to the implied-do. ... array constructor has a scope of its data-implied-do. ... ....then y again gets its type from implicit typing, and ends up as a real. ... this last 'program' should cause a compiler to barf. ...
    (comp.lang.fortran)
  • Re: Array Constructors
    ... in an array constructor, is its value always restored afterwards. ... array constructor has a scope that is just the implied-do. ... That was my initial thought, but IVF complaining if *a* variable, i, ...
    (comp.lang.fortran)