Declaring first an INTEGER scalar, and then a COMMON block where the scalar is redefined as an array, seems counterintuive (to say the least). BTW, of course the PARAMETER statement is indispensable for the code to work, right? Thanks,
> I'm happily (?) working on legacy code: should be f77, but since the
> compiler is also legacy, I'm not exactly sure about that. I stumbled
> upon this:
> COMMON /CKFIND/ aryFOO(arSize),
> . aryBAR(arSize),
> . aryGOOFY(arSize)
> Is this code standard conforming? I've never seen arrays declared this way....
Yes. At least F77; I don't recall earlier for certain but I'd say "probably".
I seem to again have lost a direct link to point to Standard-speak but to paraphrase it'll have words to the effect that if the varName in the list is an array name it can be followed by a constant specification expression for each bound in an explicit-shape array specification.
Whew!!!! There's bound to be a better way to write that, Mr Editor... :)
Anyway, in short it's ok if (as in this case) the bounds are constant and it's an explicit-shape array (as is also true here).
deltaquattro <deltaquat...@gmail.com> wrote:
> Hi,
> I'm happily (?) working on legacy code: should be f77, but > since the compiler is also legacy, I'm not exactly sure > about that. I stumbled upon this: > INTEGER arSize
> PARAMETER (arSize = 10)
> COMMON /CKFIND/ aryFOO(arSize),
> . aryBAR(arSize),
> . aryGOOFY(arSize)
> Is this code standard conforming? > I've never seen arrays declared this way. I'm used to either: > INTEGER aryFOO(arSize) ! f77 style
> INTEGER aryBAR(arSize) ! > INTEGER aryGOOFY(arSize) !
That would be usual for F77 style, but could also be
Most of the statements for separately applying attributes to
variables exist, even for Fortran 90 attributes.
> or
> INTEGER, DIMENSION(arSize) :: aryFOO, aryBAR, aryGOOFY ! f90 style
> Declaring first an INTEGER scalar, and then a COMMON block > where the scalar is redefined as an array, seems counterintuive
No, the first gives the variable the INTEGER type attribute, but
doesn't (yet) declare it a scalar.
I believe the separate attribute declaration goes back to Fortran I.
Note, though:
SUBROUTINE SURPRISE(X)
INTEGER X
DIMENSION X(:)
INTENT(OUT) X
OPTIONAL X
ASYNCHRONOUS X
VOLATILE X
TARGET X
ALLOCATABLE X
ALLOCATE (X(10))
X=3
END
It seems that the version of gfortran here doesn't support ASYNCHRONOUS, but otherwise it compiles fine.
Each statement supplies one attribute to a variable.
> (to say the least). BTW, of course the PARAMETER statement > is indispensable for the code to work, right? Thanks,
>> Declaring first an INTEGER scalar, and then a COMMON block
>> where the scalar is redefined as an array, seems counterintuive
> No, the first gives the variable the INTEGER type attribute, but
> doesn't (yet) declare it a scalar.
...
More specifically, there isn't a way to _declare_ a scalar except by implication that it hasn't been dimensioned an array after all attributes for the name have been processed and executable code is reached. (At least unless I'm forgetting something pretty major here...)
dpb <n...@non.net> wrote:
> On 7/13/2012 1:28 PM, glen herrmannsfeldt wrote:
> > deltaquattro<deltaquat...@gmail.com> wrote:
> ...
> >> Declaring first an INTEGER scalar, and then a COMMON block
> >> where the scalar is redefined as an array, seems counterintuive
> > No, the first gives the variable the INTEGER type attribute, but
> > doesn't (yet) declare it a scalar.
> ...
> More specifically, there isn't a way to _declare_ a scalar except by > implication that it hasn't been dimensioned an array after all > attributes for the name have been processed and executable code is > reached. (At least unless I'm forgetting something pretty major here...)
Heck, the elided statement doesn't even declare that aryFOO is a
variable, much less a scalar one.
integer aryFOO
specifies that aryFOO has type integer. That's pretty much all it
declares. Well, in f90 and later, it also declares that it is of default
kind.
Yes, there are things other than variables that can have types. See
functions.
This isn't a style of declaration that I personally like. But we are
sort of stuck with it for "hysterical" reasons. Although the old style
declarations have zero chance of going away, I've occasionally mused
that it might be nice to introduce a new declaration syntax that
explicitly prohibitted addition of attributes via separate statements;
then you could look at a single statement and be confident about what
was actually being declared without worry that some other statement
might change it.
-- Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
> This isn't a style of declaration that I personally like. But we are
> sort of stuck with it for "hysterical" reasons. Although the old style
> declarations have zero chance of going away, I've occasionally mused
> that it might be nice to introduce a new declaration syntax that
> explicitly prohibitted addition of attributes via separate statements;
> then you could look at a single statement and be confident about what
> was actually being declared without worry that some other statement
> might change it.
While the old form has to remain to compile old programs, it isn't
so obvious that all the new attributes needed to also work in
that form. It does seem consistent, though, to add them.
> I'm happily (?) working on legacy code: should be f77, but since the compiler > is also legacy, I'm not exactly sure about that. I stumbled upon this:
> COMMON /CKFIND/ aryFOO(arSize),
> . aryBAR(arSize),
> . aryGOOFY(arSize)
> Is this code standard conforming? I've never seen arrays declared this way.
Yes, not only is this standard conforming, but it is probably one of the most common programming styles for arrays in common blocks. The main issue with common blocks is alignment between different program units. Because they must be specified in each separate compilation unit, the most common mistake is to have inconsistent lengths, or the wrong order, or any of dozens of other unintentional mistakes related to alignment. The above style allows a programmer to see immediately that the arrays are all of the same length.
That's fine too, but then the common declaration looks like you have three scalars rather than three arrays. The programmer needs to look around for the other parts of the declarations to see that they are arrays and that they are the same size.
is probably more common. I personally never use DIMENSION statements or the DIMENSION attribute.
> Declaring first an INTEGER scalar, and then a COMMON block where the scalar > is redefined as an array, seems counterintuive (to say the least).
There are several things that are important, the array size (which is defined by the parameter value), the type (INTEGER in these cases), and the fact that they are in a common block which brings the alignment issues to the front. F77 prevents you from specifying all those things together, it requires that they be done on separate lines. So you get to pick your poison.
> BTW, of > course the PARAMETER statement is indispensable for the code to work, right?
The arrays in a common block must be declared with constants, not variables. So expressions with either parameters or literal constants are required.
Notice also that it is not possible to declare the type and value of the parameter on a single line. F77 required two lines for that too. If the two lines are next to each other, as in your example, that's not so bad, but sometimes extra lines would be inserted in between, and then the programmer had to waste some more time tracking down what was going on, particularly, as in this case, when the variable name was not consistent with the implicit typing rules.
This is another problem that f90 (and later) fixed.
> In article <7c65958f-b788-499f-890b-3475c471102f@googlegroups.com>,
> > Hi,
> > > > I'm happily (?) working on legacy code: should be f77, but since the compiler > > is also legacy, I'm not exactly sure about that. I stumbled upon this: > > > > .
> > .
> > .
> > INTEGER arSize
> > > > PARAMETER (arSize = 10) > >
> > INTEGER aryFOO
> > INTEGER aryBAR
> > INTEGER aryGOOFY
> >
> > COMMON /CKFIND/ aryFOO(arSize),
> > . aryBAR(arSize),
> > . aryGOOFY(arSize)
> > > > Is this code standard conforming? I've never seen arrays declared this way.
> Yes, not only is this standard conforming, but it is probably one of > the most common programming styles for arrays in common blocks. The > main issue with common blocks is alignment between different program > units. Because they must be specified in each separate compilation > unit, the most common mistake is to have inconsistent lengths, or > the wrong order, or any of dozens of other unintentional mistakes > related to alignment.
Ah, ok...now I understand better. This mistake is not possible in this code, since the COMMON is in a file which is INCLUDEd in all compilation unit which need the COMMON variables, but that's of. But of course, in general COMMONs do pose such a risk.
The above style allows a programmer to see
> immediately that the arrays are all of the same length.
> That's fine too, but then the common declaration looks like you have > three scalars rather than three arrays. The programmer needs to > look around for the other parts of the declarations to see that they > are arrays and that they are the same size.
> Both are alright, it is just a matter of style.
Good point :) I didn't think about that. Now I don't have the codes with me, but I seem to recall that in the last CFD codes I worked on, years ago, all COMMONs were in INCLUDE files, where arrays were declared first, and then put in COMMON blocks. In the end, since the whole file is INCLUDEd, the result is the same: misalingment is prevented. But it's very interesting to know about the reason for the other programming style. Thanks!
[..]
> > BTW, of > > course the PARAMETER statement is indispensable for the code to work, right?
> The arrays in a common block must be declared with constants, not > variables. So expressions with either parameters or literal > constants are required.
Right! It's been a very long time since the last time I used COMMONs, but I sort of recalled that array bounds in COMMONs couldn't be variables.
deltaquattro <deltaquat...@gmail.com> wrote:
> but I seem to recall that in the last CFD codes I worked on, years ago,
> all COMMONs were in INCLUDE files, where arrays were declared first, and
> then put in COMMON blocks. In the end, since the whole file is INCLUDEd,
> the result is the same: misalingment is prevented.
That's not actually 100% guaranteed to avoid such problems. It improves
your odds by a lot. In fact, it improves them by so much that I'm not
sure I recall having seen examples of errors "in the wild" when using
that style, while errors without using include were... umm... common.
There is no way to make it 100%. Fortran just provides so many ways to
do some things that it is sometimes hard to tie off all possibilities.
One thing Fortran doesn't provide is a direct way to say "I don't want
any of those others".
For example, a separate DIMENSION statement for something of the same
name as what was intended to be a scalar in the COMMON block would do
it. Or a separate COMMON statement for a COMMON of the same name; that
would be nastiest if it preceeded the included one.
> It's been a very long time since the last time I used COMMONs, but I sort
> of recalled that array bounds in COMMONs couldn't be variables.
Prior to f90, the only place array bounds could be variables was in
dummy arrays. Much easier to remember that one place that they were
allowed than the much longer list of where they were not.
-- Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
>> More specifically, there isn't a way to _declare_ a scalar except by
>> implication that it hasn't been dimensioned an array after all
>> attributes for the name have been processed and executable code is
>> reached. (At least unless I'm forgetting something pretty major here...)
> Heck, the elided statement doesn't even declare that aryFOO is a
> variable, much less a scalar one.
> integer aryFOO
> specifies that aryFOO has type integer. That's pretty much all it
> declares. Well, in f90 and later, it also declares that it is of default
> kind.
> Yes, there are things other than variables that can have types. See
> functions.
...
Yeah, I originally had a parenthetical note about the other things but it was getting long-winded so since the thread was on variables and arrays I decided to punt and just scratched it...rarely would it be where I was less instead of more verbose-- :)
glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:
> Richard Maine <nos...@see.signature> wrote:
> (snip)
> > This isn't a style of declaration that I personally like. But we are
> > sort of stuck with it for "hysterical" reasons. Although the old style
> > declarations have zero chance of going away, I've occasionally mused
> > that it might be nice to introduce a new declaration syntax that
> > explicitly prohibitted addition of attributes via separate statements;
> > then you could look at a single statement and be confident about what
> > was actually being declared without worry that some other statement
> > might change it.
> While the old form has to remain to compile old programs, it isn't
> so obvious that all the new attributes needed to also work in
> that form. It does seem consistent, though, to add them.
I once argued in committee against adding new attribute specification
statements for some new attributes that were being added in f2003. I
thought them silly things to specify in separate statements and didn't
see why they merited adding whole new statements to the language. I
forget which particular attributes were in question, but I'm
(reasonably) confident it was after f95. (I'm 100% sure it was after
f90, as I wasn't on the committee early enough to influence f90). My
argument got nowhere against the argument for consistency. I don't think
I ever got around to writing it up in a formal paper because the
reception to my oral suggestion made it obvious that it wasn't going to
fly.
The new statements might encourage a "poor" style, but at least they do
so consistently. :-(
-- Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
>> While the old form has to remain to compile old programs, it isn't
>> so obvious that all the new attributes needed to also work in
>> that form. It does seem consistent, though, to add them.
> I once argued in committee against adding new attribute specification
> statements for some new attributes that were being added in f2003. I
> thought them silly things to specify in separate statements and didn't
> see why they merited adding whole new statements to the language.
Of all the ones in my test program, the one that gfortran didn't
accept was ASYNCHRONOUS.
Rewriting a Fortran 66 program to do asynchronous I/O does seem
a little strange, though I suppose there isn't anything wrong with it.
> I forget which particular attributes were in question, but I'm
> (reasonably) confident it was after f95. (I'm 100% sure it was after
> f90, as I wasn't on the committee early enough to influence f90). My
> argument got nowhere against the argument for consistency. I don't think
> I ever got around to writing it up in a formal paper because the
> reception to my oral suggestion made it obvious that it wasn't going to
> fly.
Thinking about it again, though, to avoid the problem and not add
arbitrary restrictions on attribute order, it would have been necessary to add a new statement such as the PL/I DECLARE.
You could require the type to come first, but otherwise:
ASYNCHRONOUS, TARGET, INTENT(OUT), REAL :: X,Y,Z
If you allow that, then you might as well allow the plain
ASYNCHRONOUS statement. Otherwise, add a single new statement:
DECLARE, ASYNCHRONOUS, TARGET, INTENT(OUT), REAL :: X,Y,Z
and allow new or old attributes to be applied.
> The new statements might encourage a "poor" style, but at least > they do so consistently. :-(
It seems that way.
For comparison purposes only (I haven't written that for a while),
PL/I allows factoring of attributes. It seems that can make it
either more readable:
DCL (I,J,K,L) FIXED BIN(31,0);
or less:
DCL ((A BINARY, B DECIMAL) REAL, C COMPLEX) FLOAT(10);
> SUBROUTINE SURPRISE(X)
> INTEGER X
> DIMENSION X(:)
> INTENT(OUT) X
> OPTIONAL X
> ASYNCHRONOUS X
> VOLATILE X
> TARGET X
> ALLOCATABLE X
> ALLOCATE (X(10))
> X=3
> END
> It seems that the version of gfortran here doesn't support > ASYNCHRONOUS, but otherwise it compiles fine.
glen herrmannsfeldt wrote:
> Of all the ones in my test program, the one that gfortran didn't
> accept was ASYNCHRONOUS.
Can you elaborate? The following works for me since GCC 4.5 (added 2010-01-08; GCC 4.5.0 was released April 14, 2010):
asynchronous :: i
(Side note: In my understanding, the ASYNCHRONOUS implementation matches the changes of Technical Specification (TS) 29113 – and not only the one of Fortran 2003/2008.)
glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:
> Richard Maine <nos...@see.signature> wrote:
> (snip on old vs. new declaration form)
> >> While the old form has to remain to compile old programs, it isn't
> >> so obvious that all the new attributes needed to also work in
> >> that form. It does seem consistent, though, to add them.
> > I once argued in committee against adding new attribute specification
> > statements for some new attributes that were being added in f2003. I
> > thought them silly things to specify in separate statements and didn't
> > see why they merited adding whole new statements to the language.
> Of all the ones in my test program, the one that gfortran didn't
> accept was ASYNCHRONOUS.
Interestingly, that's one of the few that I *DO* think merits a separate
statement. In fact, you pretty much have to have one in some cases.
That's because, unlike most attributes, a variable can be ASYNCHRONOUS
in some scopes, while not being so in others. If you want to USE a
module variable and maki it asynchronous in the scope you are using it
in, then you pretty much need the separate statement, as you are not
allowed to redeclare the other attributes.
> Thinking about it again, though, to avoid the problem and not add
> arbitrary restrictions on attribute order, it would have been > necessary to add a new statement such as the PL/I DECLARE.
Yep. I'd reasonably like that option. Not sure whether it will ever
happen, but it would be one I could go for.
-- Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
>> Of all the ones in my test program, the one that gfortran didn't
>> accept was ASYNCHRONOUS.
> Can you elaborate? The following works for me since GCC 4.5 (added > 2010-01-08; GCC 4.5.0 was released April 14, 2010):
The version on this computer is 4.4.5.
Someone else maintains it, and I don't have any control over versions.
Still, it seems to me that ASYNCHRONOUS would be one of the
attributes least likely to be specified in a separate statement.
glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:
> Still, it seems to me that ASYNCHRONOUS would be one of the
> attributes least likely to be specified in a separate statement.
Was that "least likely" perhaps a typo for "most likely"? See my other
post where I mentioned it as one that was "most likely" to be used in a
separate statement. Although those weren't the exact words I used, the
idea was pretty close. If you really think it is "least likely", then I
guess we have complete disagreement on the subject.
If it was just a slip of the keyboard, well, in that case we have plenty
in common. :-)
-- Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain