For Programmers: Free Programming Magazines  


Home > Archive > Fortran > February 2007 > Array Constructors









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Array Constructors
cjk32@cam.ac.uk

2007-02-28, 8:07 am

Hello,

Can anyone confirm that when a variable is used in an implied do loop
in an array constructor, is its value always restored afterwards. For
example, if I do:


integer :: i
integer :: XYZ(8)
call date_and_time(values = XYZ)

i = 42
write (*,"(I5)") i
write (*,"(8I5)") (/(XYZ(i),i=1,8)/)
write (*,"(I5)") i

will the last line written always be 42. Intuitively, it felt like it
should be, as I would hope that the two i's are total separate.
However, IVF complained if the variable used in the array constructor
had not been declared (with implicit none set). It does works with
IVF, but I can't see anything in the documentation that states this
must always be the case.

Chris

Arjen Markus

2007-02-28, 8:07 am

On 28 feb, 12:05, c...@cam.ac.uk wrote:
> Hello,
>
> Can anyone confirm that when a variable is used in an implied do loop
> in an array constructor, is its value always restored afterwards. For
> example, if I do:
>
> integer :: i
> integer :: XYZ(8)
> call date_and_time(values = XYZ)
>
> i = 42
> write (*,"(I5)") i
> write (*,"(8I5)") (/(XYZ(i),i=1,8)/)
> write (*,"(I5)") i
>
> will the last line written always be 42. Intuitively, it felt like it
> should be, as I would hope that the two i's are total separate.
> However, IVF complained if the variable used in the array constructor
> had not been declared (with implicit none set). It does works with
> IVF, but I can't see anything in the documentation that states this
> must always be the case.
>
> Chris


I can confirm this works with g95 (on Linux) too, but
I am quite surprised: I always thought implied do-loops
were very much like ordinary do loops.

Apparently, they are not.

Still, the i within the implied do-loop is a variable and
it could have been a real too, so the compiler has every
right to complain :)

Regards,

Arjen

Michael Metcalf

2007-02-28, 8:07 am


<cjk32@cam.ac.uk> wrote in message
news:1172660739.879054.15000@q2g2000cwa.googlegroups.com...
> Hello,
>
> Can anyone confirm that when a variable is used in an implied do loop
> in an array constructor, is its value always restored afterwards.


Please note that the do variable of an implied-do in a DATA statement or an
array constructor has a scope that is just the implied-do. It is different
from any other entity with the same name (i.e., you have two variables
called i in your snippet, so to think about 'restoring' is not correct).
(See also MR&C, Section 5.15.)

Regards,

Mike Metcalf


cjk32@cam.ac.uk

2007-02-28, 7:07 pm

On 28 Feb, 12:50, "Michael Metcalf" <michaelmetc...@compuserve.com>
wrote:
> <c...@cam.ac.uk> wrote in message
>
> news:1172660739.879054.15000@q2g2000cwa.googlegroups.com...
>
>
>
> Please note that the do variable of an implied-do in a DATA statement or an
> array constructor has a scope that is just the implied-do. It is different
> from any other entity with the same name (i.e., you have two variables
> called i in your snippet, so to think about 'restoring' is not correct).
> (See also MR&C, Section 5.15.)
>


That was my initial thought, but IVF complaining if *a* variable, i,
wasn't declared somewhere in the same scope in unsettled me somewhat.
Arjen makes a good point, but if I try it with a non integer variable,
IVF complains again, saying that an integer is required. I guess this
is just a bug in the IVF compiler.

I assume 'MR&C' refers to an official fortran spec. Is that available
online anywhere?

Regards,


Chris

Michael Metcalf

2007-02-28, 7:07 pm


<cjk32@cam.ac.uk> wrote in message
news:1172673779.957168.110520@k78g2000cwa.googlegroups.com...
> On 28 Feb, 12:50, "Michael Metcalf" <michaelmetc...@compuserve.com>
>
>
> I assume 'MR&C' refers to an official fortran spec.
>

Sorry, this is "Fortran 95/2003 Explained", Metcalf, Reid &Cohen, OUP. Not
at all an official document but we try slavishly to cover the whole standard
and its interpretations.

Regards,

Mike Metcalf


Steve Lionel

2007-02-28, 7:07 pm

On Feb 28, 6:05 am, c...@cam.ac.uk wrote:

> However, IVF complained if the variable used in the array constructor
> had not been declared (with implicit none set). It does works with
> IVF, but I can't see anything in the documentation that states this
> must always be the case.


What version of IVF do you have? I took your code, added IMPLICIT
NONE and compiled it with 9.1.034 and did not get an error. Perhaps
there was a bug in an earlier version that has been fixed.


Steve Lionel
Developer Products Division
Intel Corporation
Nashua, NH

User communities for Intel Software Development Products
http://softwareforums.intel.com/
Intel Fortran Support
http://developer.intel.com/software/products/support/
My Fortran blog
http://www.intel.com/software/drfortran

Dick Hendrickson

2007-02-28, 7:07 pm

cjk32@cam.ac.uk wrote:
> On 28 Feb, 12:50, "Michael Metcalf" <michaelmetc...@compuserve.com>
> wrote:
>
> That was my initial thought, but IVF complaining if *a* variable, i,
> wasn't declared somewhere in the same scope in unsettled me somewhat.
> Arjen makes a good point, but if I try it with a non integer variable,
> IVF complains again, saying that an integer is required. I guess this
> is just a bug in the IVF compiler.


Are you using IMPLICIT NONE? If so, then all variables need to
be declared, even those with statement or construct level scope.


Dick Hendrickson
>
> I assume 'MR&C' refers to an official fortran spec. Is that available
> online anywhere?
>
> Regards,
>
>
> Chris
>

Richard Maine

2007-02-28, 7:07 pm

Dick Hendrickson <dick.hendrickson@att.net> wrote:

> Are you using IMPLICIT NONE? If so, then all variables need to
> be declared, even those with statement or construct level scope.


And I consider it an oddity that, for variables with statement or
construct scope, there is no way to declare the variable within its
scope. Instead, you have to declare the variable in the scoping unit.
This has the strange and confusing "side effect" that the same
declaration declares two different variables - the one with statement
scope and another one with scope of the scoping unit.

As Michael Metcalf pointed out, these are really two different
variables. They can even have some different properties. For example,
the one in the scoping unit can be an array, but an implied DO index in
an array constructor is always scalar. Yes, that means you can write
something like (I think I got this straight)

integer :: i(10),j(10)

...
write (*,*) [i,(j(i),i=1,10)]

The i index of the implied DO is scalar in spite of the declaration. The
other i, the one outside of the implied do, is an array.

By the way. Don't do that. Just because the standard allows it doesn't
mean that you have to code that way. Unless, of course, you are
submitting a candidate for a Fortran equivalent of the old annual
obfuscated C contest. :-(

--
Richard Maine | Good judgement comes from experience;
email: last name at domain . net | experience comes from bad judgement.
domain: summertriangle | -- Mark Twain
Klaus Wacker

2007-02-28, 7:07 pm

Dick Hendrickson <dick.hendrickson@att.net> wrote:
> cjk32@cam.ac.uk wrote:
>
> Are you using IMPLICIT NONE? If so, then all variables need to
> be declared, even those with statement or construct level scope.
>


The OP said he was using IMPLICIT NONE. I think we had this discussion
here recently. If I remember correctly: Yes, with IMPLICIT NONE you
need a type declaration for the variable with the constructor scope.
Since there is no way to put that declaration inside the scope, you
have to put it outside, at the top of the subroutine or function or
whatever. When you have a variable of the same name outside of the
constructor, the declaration applies automatically also to this
variable. So, with one declaration you declare the properties of two
things. This a somewhat confusing consequence of the fact that you
have a limited scope with no possibility to put a declaration inside.
And the outside variable cannot have a type different from the one
inside, and that type better be integer. This is also the case without
IMPLICIT NONE and without explicit type declarations.

--
Klaus Wacker klaus.wacker@udo.edu
Experimentelle Physik V http://www.physik.uni-dortmund.de/~wacker
Universitaet Dortmund Tel.: +49 231 755 3587
D-44221 Dortmund Fax: +49 231 755 4547
Richard Maine

2007-02-28, 7:07 pm

Yes. I'm following up to myself. I forgot one addition that I consider
important.

Richard Maine <nospam@see.signature> wrote:

> By the way. Don't do that.


I was saying that about a particularly obscure "feature" that I
illustrated. but it applies to the OP's posting as well. People have
explained what is going on (that there are 2 separate variables), but I
don't think anyone mentioned this suggestion:

Having the two variables of the same name causes confusion. The
confusion is well illustrated by the OP's thinking that this was one
variable whose value somehow got reset. I can se how that might be a
conclusion that someone could draw from observing behavior.

I recommend never using the same name as another variable for an implied
DO index variable in an array constructor or DATA statement. I
personally name my array constructor implied DO index variables things
like i_do in order to clearly separate them from just plain i, which is
likely to get used elsewhere.

Also note that I/O-implied DO variables are different. They do not have
their own scope, but are "ordinary" variables. There was once a time
when I was unaware of this distinction myself (and thus made a fool of
myself vehemently explaining something that turned out to be wrong. Oh
well. It happens).

--
Richard Maine | Good judgement comes from experience;
email: last name at domain . net | experience comes from bad judgement.
domain: summertriangle | -- Mark Twain
Jan Vorbrüggen

2007-02-28, 7:07 pm

> Also note that I/O-implied DO variables are different. They do not have
> their own scope, but are "ordinary" variables. There was once a time
> when I was unaware of this distinction myself (and thus made a fool of
> myself vehemently explaining something that turned out to be wrong. Oh
> well. It happens).


Is there any good reason for this, apart from "this is how the vote went" (if
anybody ever noticed before it was too late" or "we put it in so that Richard
Maine would have a chance to make a fool of himself" 8-)? I can't see a
technical need for two of the implied-do-variable types to behave one way and
the third in another.

Jan
Richard Maine

2007-02-28, 7:07 pm

Jan Vorbrüggen <jvorbrueggen@not-mediasec.de> wrote:

>
> Is there any good reason for this, apart from "this is how the vote went" (if
> anybody ever noticed before it was too late" or "we put it in so that Richard
> Maine would have a chance to make a fool of himself" 8-)? I can't see a
> technical need for two of the implied-do-variable types to behave one way and
> the third in another.


Yes, there is, unfortunately, a good reason. (Updated... Or at least a
good reason for half of the bahavior. I'm having trouble recalling th
eother half).

Implied DO indices for array constructors and DATA statements pretty
much "can't" be ordinary variables. Or anyway, if they were, one would
have to add a lot of complicated stuff laying out extra details about
tham. That's because they aren't in general done at run-time. In some
cases, array-cunstructor implied DOs can be run-time things, but in
other cases, they can't (such as when used in an initializer). DATA
statement implied DOs never are. If you tried to describe these as
variables with scope broader than the implied DO, you'd have to define
concepts of ordering... an awful lot like describing execution ordering.

As for the I/O ones. Hmm. I was thinking I recalled some reason, but it
escapes me at the moment. (No, it is not so that you can read
(a(i),i=1,n) and deduce how many elements you sucessfully got in a
too-short record by examining the value of i; that would be
nonstandard.)

Do note that both I/O and DATA statement implied do loops go "way back".
So the difference isn't something new. People wouldn't yet have had a
chance to get annoyed enough at me to want to give me the chance to make
a fool of myself. Well, my parents were probably pretty frustrated, but
that's another matter. :-)

--
Richard Maine | Good judgement comes from experience;
email: last name at domain . net | experience comes from bad judgement.
domain: summertriangle | -- Mark Twain
Jan Vorbrüggen

2007-02-28, 7:07 pm

> As for the I/O ones. Hmm. I was thinking I recalled some reason, but it
> escapes me at the moment.


That would have been my point: Why are the I/O implied-dos "normal" loops
instead like the others?

> Do note that both I/O and DATA statement implied do loops go "way back".
> So the difference isn't something new. People wouldn't yet have had a
> chance to get annoyed enough at me to want to give me the chance to make
> a fool of myself. Well, my parents were probably pretty frustrated, but
> that's another matter. :-)


Hmmm...has that difference been pointed out, with all its consequences, in
the Fortran standard prior to F90?

Jan

Jugoslav Dujic

2007-02-28, 7:07 pm

Jan Vorbrüggen wrote:
|| Also note that I/O-implied DO variables are different. They do not have
|| their own scope, but are "ordinary" variables. There was once a time
|| when I was unaware of this distinction myself (and thus made a fool of
|| myself vehemently explaining something that turned out to be wrong. Oh
|| well. It happens).
|
| Is there any good reason for this, apart from "this is how the vote went" (if
| anybody ever noticed before it was too late" or "we put it in so that Richard
| Maine would have a chance to make a fool of himself" 8-)? I can't see a
| technical need for two of the implied-do-variable types to behave one way and
| the third in another.

Let me pile on Jan's questions: if it was decided that implied DO-loop variables
were different (IMO reasonably), why weren't they simply dismissed from
the "scope" of IMPLICIT NONE? (IOW, they could be left undeclared and
integer-by-default). I still have to put "INTEGER, PRIVATE:: k" at the top
of my modules whenever I use k in an implied-DO of an initialization statement.

--
Jugoslav
___________
www.xeffort.com

Please reply to the newsgroup.
You can find my real e-mail on my home page above.

Steve Lionel

2007-02-28, 7:07 pm

On Feb 28, 12:52 pm, Jan Vorbr=FCggen <jvorbrueg...@not-mediasec.de>
wrote:

>
> Hmmm...has that difference been pointed out, with all its consequences, in
> the Fortran standard prior to F90?


More or less. Fortran 77 says, for data-implied-do:

"The appearance of an implied-DO-variable name in a DATA statement
does not affect the definition status of a variable of the same name
in the same program unit."

There is no similar text for I/O implied DO and the wording in F77 and
later indicates that it is processed like a normal DO, as noted by
others in this thread.

Steve

glen herrmannsfeldt

2007-02-28, 7:07 pm

Jan Vorbrüggen wrote:

[color=darkred]
> Is there any good reason for this, apart from "this is how the vote
> went" (if anybody ever noticed before it was too late" or "we put it in
> so that Richard Maine would have a chance to make a fool of himself"
> 8-)? I can't see a technical need for two of the implied-do-variable
> types to behave one way and the third in another.


Because they are different. Note, first, the I/O implied DO goes back
to Fortran I, when 32K was a lot of memory. As Richard says, I go
to implementation too soon, but it is easier to see that way.
Implementations are allowed to, and often do, use a real loop for
an I/O implied DO. For the simpler cases it is likely that loop is
internal to the I/O routine, but for more complicated cases it is
likely part of the I/O statement. Consider:

READ(*,*) J,(A(INT(SQRT(REAL(I)))),I=1,J)

at least through the Fortran 66 days, and likely through Fortran 77
it was reasonable to allow I to be a normal variable.

For DATA statements which initialize data, and are not executable
statements, if there is an actual variable it is used before the
program execution begins. (Some would say compile time, and that
is likely the usual implementation.) It is a little less obvious for
array constructors, but if you consider it as an array constant,
similar to an array initialized in a DATA statement before execution
begins, it makes more sense.

For array constructors, it isn't so obvious. I am not sure about
something like:

write(*,"(8I5)") j,(/(XYZ(i),i=1,j)/)

Though in the above the array can be constructed before execution
of the WRITE begins. I don't believe that you can do:

read(*,"(8I5)") j,(/(XYZ(i),i=1,j)/)

so it seems that there are some differences between I/O implied
DO and array constructor implied DO.

-- glen

glen herrmannsfeldt

2007-02-28, 7:07 pm

Steve Lionel wrote:

(snip)
> More or less. Fortran 77 says, for data-implied-do:


> "The appearance of an implied-DO-variable name in a DATA statement
> does not affect the definition status of a variable of the same name
> in the same program unit."


> There is no similar text for I/O implied DO and the wording in F77 and
> later indicates that it is processed like a normal DO, as noted by
> others in this thread.


The rule for normal DO in F66 was that the DO variable was undefined
after the loop terminated normally. If you GOTO out of the loop,
the DO variable kept its value. As I found out somewhere along the
way (I almost sent a bug report to DEC), the END= exit from a READ
statement is NOT like a GOTO out of a real DO loop. The implementation
is allowed to, but not required to, store into the I/O implied DO variable.

-- glen

glen herrmannsfeldt

2007-02-28, 7:07 pm

Richard Maine wrote:

(snip)

> Do note that both I/O and DATA statement implied do loops go "way back".
> So the difference isn't something new. People wouldn't yet have had a
> chance to get annoyed enough at me to want to give me the chance to make
> a fool of myself. Well, my parents were probably pretty frustrated, but
> that's another matter. :-)


I/O implied DO back to Fortran I in 1956. DATA statements have always
been non-executable statements. It seems that DATA implied DO came in
Fortran 77.

As for variables that don't really exist, but have to be declared
anyway, consider the dummy arguments for statement functions.

Hmmm. Since Fortran 77 allows DO variables to be REAL, maybe
DATA implied DO variables can also be REAL. That would be a reason
you would need to declare them.

-- glen

Richard Maine

2007-02-28, 7:07 pm

Jan Vorbrüggen <jvorbrueggen@not-mediasec.de> wrote:

>
> Hmmm...has that difference been pointed out, with all its consequences, in
> the Fortran standard prior to F90?


What do you mean by "pointed out, with all its consequences". The
standard is not and has never been a tutorial document. The facts on
this are there, pretty explicitly and clearly (as much as standard-speak
ever is), in at least f77, and probably f66, though I don't care to
research that. It is not the job of the standard to lecture on
consequences.

--
Richard Maine | Good judgement comes from experience;
email: last name at domain . net | experience comes from bad judgement.
domain: summertriangle | -- Mark Twain
Richard Maine

2007-02-28, 7:07 pm

Jugoslav Dujic <jdujic@yahoo.com> wrote:

> Let me pile on Jan's questions: if it was decided that implied DO-loop
> variables were different (IMO reasonably), why weren't they simply
> dismissed from the "scope" of IMPLICIT NONE?


You have left the realm of questions that I can meaningfully answer. It
isn't as though I was there. The conflict in question arose in f77 and
earlier. Implicit none wasn't standardized until f90, but it followed
earlier practice, and I wasn't there for f90 either. So anything I could
say would be nothing but speculation. And I don't feel that I have any
spectacularly good speculation either.

The best I could say is that it doesn't seem consistent with the notion
of implicit none. There are lots of things that don't "need" declaring.
With implicit none, you are saying that you want to make all the
declarations explicit, whether they were needed or not.

But don't expect any fine detailed analysis of the exact arguments made
at the time. I don't have any such thing. I rather doubt than anyone
else does either. If you ask for my guess, I'd guess that it didn't even
come up - that implicit none was standardized as adoption of existing
practice.

--
Richard Maine | Good judgement comes from experience;
email: last name at domain . net | experience comes from bad judgement.
domain: summertriangle | -- Mark Twain
robert.corbett@sun.com

2007-02-28, 7:07 pm

On Feb 28, 10:57 am, glen herrmannsfeldt <g...@ugcs.caltech.edu>
wrote:

> Though in the above the array can be constructed before execution
> of the WRITE begins. I don't believe that you can do:
>
> read(*,"(8I5)") j,(/(XYZ(i),i=1,j)/)
>
> so it seems that there are some differences between I/O implied
> DO and array constructor implied DO.


The reason an array constructor is not allowed as
an input item is that an array constuctor is not a
variable. In C terms, an array constructor is an
rvalue and an input item must be an lvalue. The
statement

READ (*, '(8I5)') J, M + N

is not allowed for the same reason. And, yes, I know
it might be allowed in Fortran 2008.

Bob Corbett

John Harper

2007-02-28, 10:05 pm

In article <54lr81F2066j0U2@mid.individual.net>,
Jan Vorbrüggen <jvorbrueggen@not-mediasec.de> wrote:
>
>Is there any good reason for this, apart from "this is how the vote went" (if
>anybody ever noticed before it was too late" or "we put it in so that Richard
>Maine would have a chance to make a fool of himself" 8-)? I can't see a
>technical need for two of the implied-do-variable types to behave one way and
>the third in another.


Scope of implied-do variables isn't the only way in which the behaviour
is different, alas. If string is a character variable of length n, you
can have (string(i:i), i=1,n) in i/o or an array constructor but not in
a data statement (not even if string is a structure component, as was
gently pointed out in another thread recently when I got that wrong).
For example this program uses what I believe to be the two valid cases:

INTEGER,PARAMETER:: n = 6
CHARACTER:: carray(n)*1, string*(n) = 'foobar'
carray = (/ (string(i:i),i=1,n) /) ! array constructor
PRINT *, carray
PRINT *, (string(i:i),i=1,n) ! io-implied-do
END

This difference between the 3 types of implied-do would seem to be just
as superfluous as Jan's. Does forbidding it in DATA prevent some evil
that I haven't thought of?

-- John Harper, School of Mathematics, Statistics and Computer Science,
Victoria University, PO Box 600, Wellington 6140, New Zealand
e-mail john.harper@vuw.ac.nz phone (+64)(4)463 5341 fax (+64)(4)463 5045
robert.corbett@sun.com

2007-02-28, 10:05 pm

On Feb 28, 5:20 pm, har...@mcs.vuw.ac.nz (John Harper) wrote:

> This difference between the 3 types of implied-do would seem to be just
> as superfluous as Jan's. Does forbidding it in DATA prevent some evil
> that I haven't thought of?


No, it does not. The constraint is sloppy. I am sure that if the
members of J3 had thought about that case, the constraint would
have been loosened to allow it.

Bob Corbett

Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com