From: steve on
Given the code

integer i
i = 5
print *, (/ (i, i = 1, i) /) ! i has the scope of the implied-do
print *, i ! i should be 5 as it is in an
outer scope
end

What is the expected output and what is the correct output? The
question is whether the i in the scalar-int-expr m2 is uninitialized
or not?

--
steve
From: Richard Maine on
steve <kargls(a)comcast.net> wrote:

> Given the code
>
> integer i
> i = 5
> print *, (/ (i, i = 1, i) /) ! i has the scope of the implied-do
> print *, i ! i should be 5 as it is in an
> outer scope
> end
>
> What is the expected output and what is the correct output? The
> question is whether the i in the scalar-int-expr m2 is uninitialized
> or not?

The code is illegal so there is no "expected" or "correct" output. The i
in the outer scope has nothing to do with the implied DO loop. In f2003,
see 16.3, which tells you that the scope of the ac-do-variable (that's
the inner i) is the ac-implied-do. Then in R470, see that ac-implied-do
includes the "m2" scalar expression. Thus, any i in that expression is
the inner one. But the expression is evaluated before the inner one is
defined. Subclause 4.7 refers to the DO construct for how initialization
and execution of an ac-implied-do work, and 8.1.6.4.1 makes it quite
explicit that the loop control expressions are evaluated prior to the DO
variable becomming defined.

Hmm. One might argue that the inner-scope i remains defined after
execution of the implied do, as I don't say anything saying it becomes
undefined. That might make things different for the second pass through
this code (if there were such a second pass). But I don't see how one
could get past the first pass anyway.

The standard doesn't make it clear (at all), but an ac-implied-do is a
bit of an odd thing in that, although it is descibed as being like a DO
contruct, it doesn't necessarily have any execution-time behavior at
all. You can, for example, have an ac-implied-do in an initialization
expression. That might be part of why there isn't anything saying that
the ac-implied-do variable becomes undefined when the loop is done -
that might not have an identifiable place in the execution sequence.

In any case, I can see no way by which the code shown is legal. Setting
a value for the outer scope i is just an irrelevant distraction.

--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
From: steve on
On May 31, 4:07 pm, nos...(a)see.signature (Richard Maine) wrote:
> steve <kar...(a)comcast.net> wrote:
> > Given the code
>
> >    integer i
> >    i = 5
> >    print *, (/ (i, i = 1, i) /)   ! i has the scope of the implied-do
> >    print *, i                        ! i should be 5 as it is in an
> > outer scope
> >    end
>
> > What is the expected output and what is the correct output?  The
> > question is whether the i in the scalar-int-expr m2 is uninitialized
> > or not?
>
> The code is illegal so there is no "expected" or "correct" output. The i
> in the outer scope has nothing to do with the implied DO loop. In f2003,
> see 16.3, which tells you that the scope of the ac-do-variable (that's
> the inner i) is the ac-implied-do. Then in R470, see that ac-implied-do
> includes the "m2" scalar expression. Thus, any i in that expression is
> the inner one. But the expression is evaluated before the inner one is
> defined. Subclause 4.7 refers to the DO construct for how initialization
> and execution of an ac-implied-do work, and 8.1.6.4.1 makes it quite
> explicit that the loop control expressions are evaluated prior to the DO
> variable becomming defined.
>
> Hmm. One might argue that the inner-scope i remains defined after
> execution of the implied do, as I don't say anything saying it becomes
> undefined. That might make things different for the second pass through
> this code (if there were such a second pass). But I don't see how one
> could get past the first pass anyway.
>
> The standard doesn't make it clear (at all), but an ac-implied-do is a
> bit of an odd thing in that, although it is descibed as being like a DO
> contruct, it doesn't necessarily have any execution-time behavior at
> all. You can, for example, have an ac-implied-do in an initialization
> expression. That might be part of why there isn't anything saying that
> the ac-implied-do variable becomes undefined when the loop is done -
> that might not have an identifiable place in the execution sequence.
>
> In any case, I can see no way by which the code shown is legal. Setting
> a value for the outer scope i is just an irrelevant distraction.
>

Once again thanks Richard! I've been puzzling over this
for an good hour or two. My original thought was that
the code was illegal, but as I tried to trace through the
F2003 standard I became somewhat confused (Okay, more
confused than more normal state of confusion). The only
clause I found that I could digest to support my original
thought is in:

16.5.7 Variable definition context

Some variables are prohibited from appearing in a syntactic
context that would imply definition or undefinition of the
variable (5.1.2.7, 5.1.2.12, 12.6). The following are the
contexts in which the appearance of a variable implies such
definition or undefinition of the variable:
....
(3) A do-variable in a do-stmt or io-implied-do,

BTW, this came up as

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44354

--
steve
From: Richard Maine on
steve <kargls(a)comcast.net> wrote:

> On May 31, 4:07 pm, nos...(a)see.signature (Richard Maine) wrote:

> > The standard doesn't make it clear (at all), but an ac-implied-do is a
> > bit of an odd thing in that, although it is descibed as being like a DO
> > contruct, it doesn't necessarily have any execution-time behavior at
> > all.
....
> 16.5.7 Variable definition context
>
> ...The following are the
> contexts in which the appearance of a variable implies such
> definition or undefinition of the variable:
> ....
> (3) A do-variable in a do-stmt or io-implied-do,

I don't blame you for being confused. (Well, "blame" would not be quite
the right concept anyway, but I'm sure you know what I mean.) I have in
the past made a simillar error in thinking that an io-implied-do was a
lot like an ac-implied-do. I think it was even in committee that I once
made a misstatement based on thinking they were simillar. I forget what
the misstatement was, but I recall that it came from incorrectly
thinking those forms were simillar.

What you have is an ac-implied-do, not an io-implied-do. Yes, I know it
is in an i/o list, but the syntax is not that of an io-implied-do. It is
in an array constructor. So the bit you quoted above does not apply, as
it is not for array constructors.

An io-implied-do variable does *NOT* have statement scope. Read through
16.3 (I just did to make sure; admitedly I skimmed quickly, but I think
I'd have seen it). I don't think you will find io-implied-do mentioned
therein.

An io-implied-do just uses a "normal" variable from the scoping unit.
Also, its definition does have a place in the normal execution sequence.
I think that is probably a critical part of the difference - that array
constructors aren't necessarily evaluated during execution time.

Now if you take the (/ and /) out of your example code, you would then
have an io-implied-do, and my answer would be different.

--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
From: jfh on
On Jun 1, 11:07 am, nos...(a)see.signature (Richard Maine) wrote:
> steve <kar...(a)comcast.net> wrote:
> > Given the code
>
> >    integer i
> >    i = 5
> >    print *, (/ (i, i = 1, i) /)   ! i has the scope of the implied-do
> >    print *, i                        ! i should be 5 as it is in an
> > outer scope
> >    end
>
> > What is the expected output and what is the correct output?  The
> > question is whether the i in the scalar-int-expr m2 is uninitialized
> > or not?
>
> The code is illegal so there is no "expected" or "correct" output. The i
> in the outer scope has nothing to do with the implied DO loop. In f2003,
> see 16.3, which tells you that the scope of the ac-do-variable (that's
> the inner i) is the ac-implied-do. Then in R470, see that ac-implied-do
> includes the "m2" scalar expression. Thus, any i in that expression is
> the inner one. But the expression is evaluated before the inner one is
> defined. Subclause 4.7 refers to the DO construct for how initialization
> and execution of an ac-implied-do work, and 8.1.6.4.1 makes it quite
> explicit that the loop control expressions are evaluated prior to the DO
> variable becomming defined.
>
> Hmm. One might argue that the inner-scope i remains defined after
> execution of the implied do, as I don't say anything saying it becomes
> undefined. That might make things different for the second pass through
> this code (if there were such a second pass). But I don't see how one
> could get past the first pass anyway.
>
> The standard doesn't make it clear (at all), but an ac-implied-do is a
> bit of an odd thing in that, although it is descibed as being like a DO
> contruct, it doesn't necessarily have any execution-time behavior at
> all. You can, for example, have an ac-implied-do in an initialization
> expression. That might be part of why there isn't anything saying that
> the ac-implied-do variable becomes undefined when the loop is done -
> that might not have an identifiable place in the execution sequence.
>
> In any case, I can see no way by which the code shown is legal. Setting
> a value for the outer scope i is just an irrelevant distraction.
>
> --
> Richard Maine                    | Good judgment comes from experience;
> email: last name at domain . net | experience comes from bad judgment.
> domain: summertriangle           |  -- Mark Twain

Quality-of-implementation comment: ifort objects to the program at
compile time, but 3 other compilers compiled and ran it, printing two
different results. They were not obliged to point out the illegality
of the program because no constraint was violated. But when you get
different results from different compilers (that are not attributable
to differences in implementation-dependent things such as floating
point arithmetic or treatment of * format) you almost always have a
bad program, but occasionally (though not in this case) you have been
bitten by a compiler bug.

-- John Harper