is the following program valid or not? I have the feeling that it is
invalid, but I cannot find it in the standard. Most compilers happily
eat the code, but ifort prints a warning (!),
warning #6755: A COMMON block data object may not have the SAVE attribute.
and openf95/sunf95/pathf95 (which seem to have a common ancestor) print:
ERROR: Object "I2" has the SAVE attribute, so it must not be
equivalenced to an object in a common block.
I found the following clause
"C517 (R501) The SAVE attribute shall not be specified for an object
that is in a common block [...]"
but I currently don't see how this restriction propagates to an object
that is equivalenced to a common-block object.
Example:
implicit none
integer :: i1, i2
common /block/ i1
save i2
equivalence(i1,i2)
end
Tobias
SAVE means don't destroy on exit from the subroutine.
If one item in a common block (equivalenced or not - that's just
another alias for that memory are and possibly a change of variable
type usage), then all the common block logically has to be saved too;
so the compiler sees a conflict.
It's all a question of memory management, static or dynamic.
> is the following program valid or not? I have the feeling that it is
> invalid, but I cannot find it in the standard. Most compilers happily
> eat the code, but ifort prints a warning (!),
> warning #6755: A COMMON block data object may not have the SAVE attribute.
Yes, the COMMON block itself should have the SAVE attribute, but not
the variables in the block.
> and openf95/sunf95/pathf95 (which seem to have a common ancestor) print:
> ERROR: Object "I2" has the SAVE attribute, so it must not be
> equivalenced to an object in a common block.
> I found the following clause
> "C517 (R501) The SAVE attribute shall not be specified for an object
> that is in a common block [...]"
> but I currently don't see how this restriction propagates to an object
> that is equivalenced to a common-block object.
EQUIVALENCE to a COMMON variable makes that variable in the block.
> Example:
> implicit none
> integer :: i1, i2
> common /block/ i1
> save i2
> equivalence(i1,i2)
> end
Note that this is exactly the same as:
implicit none
integer :: i1, i2
common /block/ i2
save i2
equivalence(i1,i2)
end
EQUIVALENCE doesn't have a direction, it is symmetric.
The two (or more) variables are equivalent to each other.
There are many interesting cases involving COMMON and EQUIVALENCE.
integer x(10),y(100),z(50)
common x
equivalence (x,y),(y(100),z(1))
Now all three arrays are in common, and the common block is
149 storage units long.
common a,b,c,d,e,f
dimension x(10)
equivalence (a,x)
x(6)=6
c=3
print *,f,x(3)
Note that only a and x are listed in the equivalence statement,
but a through f are now equivalenced to x(1) through x(6).
-- glen
> warning #6755: A COMMON block data object may not have the SAVE attribute.
As Glen said, the warning is correct (for portability). It's moot until
we encounter an implementation where COMMON is not necessarily SAVEd.
This last type of construct was sometimes used on MS-DOS to hold
register contents while calling a DOS interrupt. After setting
individual "registers", the service routine was called with an array
as an argument. Return values appeared in the "registers" as well.
[I don't remember if any CP/M Fortrans did this.]
-- e
>>
>> common a,b,c,d,e,f
>> dimension x(10)
>> equivalence (a,x)
>> x(6)=6
>> c=3
>> print *,f,x(3)
>>
>> Note that only a and x are listed in the equivalence statement,
>> but a through f are now equivalenced to x(1) through x(6).
>>
>> -- glen
>
> This last type of construct was sometimes used on MS-DOS to hold
> register contents while calling a DOS interrupt. After setting
> individual "registers", the service routine was called with an array
> as an argument. Return values appeared in the "registers" as well.
> [I don't remember if any CP/M Fortrans did this.]
>
> -- e
For CP/M Fortran, you're talking about f66 at best, with no SAVE
available, so forcing variables into COMMON was a legitimate alternative
to the typical assumption that something like SAVE would always be in force.
These were often overlaid implementations so that common would not be saved
unless it was in the root segement. One had to use overlay controls to have
the common partway down the overlay structure. If the overlay processor was
clever it could figure out how far down to put things. The easy fix was to
reference the common in the main so it always stayed in scope and in the
root segment.
Overlays were common on mainframes as well as MS/DOS. I seem to recall them
on the MS Fortran I used on CP/M (on a Softcard in my Apple ][).
Overlays are an easy example of why DATA had it semantics which were not those
of SAVE until the standard specified that DATA implied SAVE.
!!!!! On those systems, as under IBM MVT, you needed to overlay
many programs up to the eyeballs to fit them into the space available,
and that included overlaying COMMON. If you wanted to achieve that
effect, you (a) put them into COMMON and (b) declared that COMMON in
the main program. That gave you the effect you wanted, and it was
even defined behaviour (10.2.5, page 29, of Fortran 66).
Regards,
Nick Maclaren.
> There are many interesting cases involving COMMON and EQUIVALENCE.
>
> integer x(10),y(100),z(50)
>
> common x
> equivalence (x,y),(y(100),z(1))
>
> Now all three arrays are in common, and the common block is
> 149 storage units long.
I've been sorting this out the last couple weeks. I think I made a
breakthrough when I read the MR&C version of this material, but that's
taken me from where I was compleatly blocked to a state of
semi-comprehension.
Did you get all the keystrokes right here:
integer x(10),y(100),z(50)
common x
equivalence (x,y),(y(100),z(1))
x = 7
print *, "x is ", x
print *, "y is ", y
print *, "z is ", z
endprogram
! g95 common1.F90 -Wall -o f.exe
C:\MinGW\source>g95 common1.F90 -Wall -o f.exe
C:\MinGW\source>f
x is 7 7 7 7 7 7 7 7 7 7
y is 7 7 7 7 7 7 7 7 7 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
z is 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0
C:\MinGW\source>
--
larry gates
As with all the other proposals, it's basically just a list of words.
You can deal with that... :-)
-- Larry Wall in <1997090323...@wall.org>
Then try adding a CALL SUB
where SUB is
subroutine sub
common heavens(109),to_betsy(40)
print *, heavens, to_betsy
end
Dick Hendrickson
> common a,b,c,d,e,f
> dimension x(10)
> equivalence (a,x)
> x(6)=6
> c=3
> print *,f,x(3)
>
> Note that only a and x are listed in the equivalence statement,
> but a through f are now equivalenced to x(1) through x(6).
An interesting program. My output had six and three as reals. I thought
this program made the point just as well:
implicit integer (a-z)
common a,b,c,d,e,f
dimension x(10)
equivalence (a,x)
c=6
x(c)=c
c=3
print *,f,x(c)
endprogram
! g95 common2.F90 -Wall -o g.exe
C:\MinGW\source>g95 common2.F90 -Wall -o g.exe
C:\MinGW\source>g
6 3
C:\MinGW\source>
--
larry gates
Call me bored, but don't call me boring.
-- Larry Wall in <1997051019...@wall.org>
It's likely to be a more general statement. There are a ton
of attributes and I don't know where there is a statement
about how they propagate in an equivalence. The ones that
sound like trouble are SAVE, ASYNCHRONOUS, VOLATILE,
PROTECTED, and maybe BIND(C).
Given something like
dimension x(2)
troublesome attribute :: y
equivalence ( x(2), y)
does x(2) also have the attribute? How about x(1)?
I need to go babysit a sick grandson, But this might
give you some more places to look. You can always read
chapter 16; never hurts, might help.
Dick Hendrickson
Dick Hendrickson
> I couldn't find anything either. I tried chapter 16 which
> is full of association stuff, but no luck. The answer has
> to be what you think, it's illegal. You just can't sneak
> a SAVE into the middle of a common block.
There is a very close association between COMMON and EQUIVALENCE.
Some of this is in 5.5.2 in Fortran 2003.
In 5.5.2.1: "Data objects associated with an entity in a common
block are considered to be in that common block."
In 5.5.2.2: "The size of a common block is the size of its common
block storage sequence, including any extensions
of the sequence resulting from equivalence association."
-- glen
> Dick Hendrickson wrote:
> (snip on COMMON and EQUIVALENCE)
>
> > I couldn't find anything either. I tried chapter 16 which
> > is full of association stuff, but no luck. The answer has
> > to be what you think, it's illegal. You just can't sneak
> > a SAVE into the middle of a common block.
>
> There is a very close association between COMMON and EQUIVALENCE.
>
> Some of this is in 5.5.2 in Fortran 2003.
>
> In 5.5.2.1: "Data objects associated with an entity in a common
> block are considered to be in that common block."
Yes. I think Dick was just (quite understandably) looking for the wrong
thing. You won't find separate restrictions on the attributes of things
that are equivalenced to variables in common because separate
restrictions aren't needed. The variables so equivalenced are in the
common, by the above citation, and thus the usual restrictions on
variables in common apply.
--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
>>There is a very close association between COMMON and EQUIVALENCE.
> Yes. I think Dick was just (quite understandably) looking for the wrong
> thing. You won't find separate restrictions on the attributes of things
> that are equivalenced to variables in common because separate
> restrictions aren't needed. The variables so equivalenced are in the
> common, by the above citation, and thus the usual restrictions on
> variables in common apply.
Otherwise the statement should have been called "SIMILAR TO"
instead of EQUIVALENCE.
-- glen
> The problem here is that y and z have undefined values.
> Try putting
> y = 100
> z = 200
> before the x=7 line, and after you understand that, put
> them after the x=7 line. That should help you see what
> equivalence does.
integer x(10),y(100),z(50)
common x
equivalence (x,y),(y(100),z(1))
x = 7
y = 100
z = 200
print *, "x is ", x
print *, "y is ", y
print *, "z is ", z
endprogram
! g95 common1.F90 -Wall -o f.exe
C:\MinGW\source>g95 common1.F90 -Wall -o f.exe
C:\MinGW\source>f
x is 100 100 100 100 100 100 100 100 100 100
y is 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100
100 1
00 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100
100 1
00 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100
100 1
00 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100
100 1
00 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100
100 1
00 200
z is 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200
200 2
00 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200
200 2
00 200 200 200 200 200 200 200 200 200 200 200
C:\MinGW\source>
Hmmm. I'll need to think about this for a bit.
Dick, do you have the source for the examples from §14? It's more
keystrokes than I can do right now.
--
larry gates
echo "Your stdio isn't very std."
-- Larry Wall in Configure from the perl distribution
Are Y or Z SAVEd? Or Y(2), but not Y(1) or Y(3)?
Same question for ASYNCHRONOUS and VOLATILE.
C584 says that PROTECTED is a special case, either all of the
equivalence set or none of it can have the PROTECTED attribute.
But, I didn't see anything similar about SAVE, VOLATILE, or
ASYNCHRONOUS. Note that there is no COMMON in the example.
Dick Hendrickson
> Good find. I had completely forgotten about that. But, you
> guys didn't answer the second half of my question. Given
> SAVE :: X
> REAL :: Y(3)
> EQUIVALENCE (X, Y(2)) (X, Z)
>
> Are Y or Z SAVEd? Or Y(2), but not Y(1) or Y(3)?
> Same question for ASYNCHRONOUS and VOLATILE.
>
> C584 says that PROTECTED is a special case, either all of the
> equivalence set or none of it can have the PROTECTED attribute.
> But, I didn't see anything similar about SAVE, VOLATILE, or
> ASYNCHRONOUS. Note that there is no COMMON in the example.
Yeah. I didn't answer because that's a harder case. :-)
Seems to me that at least Y(2) is effectively saved, whether it calls it
that or not, because X is going to retain its definition status, and
thus so will Y(2). Hmm. Though I suppose one could invert that logic and
say that if Y wasn't saved, that it became undefined and thus X also
did.
On the whole, I'd think that all of the equivalence set pretty much
better be saved, either explicitly or implicitly, or something is going
to look inconsistent... but I'm not sure if or where the standard says
that.
> The problem here is that y and z have undefined values.
> Try putting
> y = 100
> z = 200
> before the x=7 line, and after you understand that, put
> them after the x=7 line. That should help you see what
> equivalence does.
>
> Then try adding a CALL SUB
> where SUB is
> subroutine sub
> common heavens(109),to_betsy(40)
> print *, heavens, to_betsy
> end
>
>
> Dick Hendrickson
I've got output that I think illustrates what Dick is getting at; I'm a
little shaky with it still:
implicit integer (h-t)
integer x(10),y(100),z(50)
common x
equivalence (x,y),(y(100),z(1))
x = 333
do i=1, 100
y(i)=i
enddo
z = 23
print *, "x is ", x
print *, "y is ", y
print *, "z is ", z
call sub
contains
subroutine sub
common heavens(109),to_betsy(40)
print *, "heavens is ", heavens
print *, "to_betsy is ", to_betsy
end subroutine
endprogram
! g95 common3.F90 -Wall -o f.exe
C:\MinGW\source>g95 common3.F90 -Wall -o f.exe
C:\MinGW\source>f
x is 1 2 3 4 5 6 7 8 9 10
y is 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
27 2
8 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
53 54
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
80 81
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 23
z is 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23
23 2
3 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23
23
heavens is 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
25 2
6 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
51 52
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
78 79
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 23 23 23 23 23
23 2
3 23 23 23
to_betsy is 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23
23 23
23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23
C:\MinGW\source>
One thing notable is that heavens only goes up to 99. I would expectr that
in C but not Fortran.
In light of these data, can someone talk through what happens with the
common, the equivalence, and execution?
The initial value of x is irrelevant.
If you were to make the two rows of rectangles to show storage, what would
that looke like for this? X seems to be the first ten squares in y. What
forces all the z's to be 23?
Hmmm.
--
larry gates
Not that I'm against sneaking some notions into people's heads upon
occasion. (Or blasting them in outright.)
-- Larry Wall in <1997102116...@wall.org>
implicit integer (h-t)
integer x(10),y(100),z(50)
common x
equivalence (x,y),(y(100),z(1))
By how much is the extension of x here?
--
larry gates
If you want to see useful Perl examples, we can certainly arrange to have
comp.lang.misc flooded with them, but I don't think that would help the
advance of civilization. :-)
-- Larry Wall in <1992Mar5.1...@netlabs.com>
>>There is a very close association between COMMON and EQUIVALENCE.
>>Some of this is in 5.5.2 in Fortran 2003.
>>In 5.5.2.1: "Data objects associated with an entity in a common
>> block are considered to be in that common block."
>>In 5.5.2.2: "The size of a common block is the size of its common
>> block storage sequence, including any extensions
>> of the sequence resulting from equivalence association."
> implicit integer (h-t)
> integer x(10),y(100),z(50)
> common x
> equivalence (x,y),(y(100),z(1))
> By how much is the extension of x here?
Well, the common block but not really x.
The extension is 49 storage units. z(50) would correspond
to x(149). If you have bounds checking off it probably does.
If you put
real a
common a(149)
in another routine then a(149) would correspond to z(50) and the
two common blocks would have the same length.
-- glen
> On the whole, I'd think that all of the equivalence set
> pretty much better be saved, either explicitly or
> implicitly, or something is going to look inconsistent...
> but I'm not sure if or where the standard says that.
I think you might have been misled by the examples presented
so far in this thread. Other examples might lead to other
conclusions.
Consider the declarations
INTEGER I
REAL X
EQUIVALENCE (I, X)
SAVE X
Assume neither I nor X have the TARGET attribute. The
variables I and X are storage associated, but that does
not mean that a standard-conforming implementation is
required to use the same storage for them. A
standard-conforming implementation would be free to
allocate I to an integer register and X to a
floating-point register. Assuming registers are not saved
after a return, the variable X would have to be stored
before the containing routine exits and restored if and
when the routine is re-entered. The value of the
variable I, on the other hand, could be lost following the
return.
The description of when variables become undefined in
Section 17.3 of the FORTRAN 77 standard makes it plain
that the variable I becomes undefined when the program
exits the routine that contains it. Later Fortran
standards are less clear, but I suspect the intent is the
same. There is no mention of a change in this area in the
compatibility sections of the standards.
Bob Corbett
and then tracer through what an assignment to any element does to
the others.
Dick Hendrickson
Dick Hendrickson
> Larry Gates wrote:
> (snip, I wrote)
>
>>>There is a very close association between COMMON and EQUIVALENCE.
>
>>>Some of this is in 5.5.2 in Fortran 2003.
>
>>>In 5.5.2.1: "Data objects associated with an entity in a common
>>> block are considered to be in that common block."
>
>>>In 5.5.2.2: "The size of a common block is the size of its common
>>> block storage sequence, including any extensions
>>> of the sequence resulting from equivalence association."
>
>> implicit integer (h-t)
>> integer x(10),y(100),z(50)
>
>> common x
>> equivalence (x,y),(y(100),z(1))
>
>> By how much is the extension of x here?
>
> Well, the common block but not really x.
That's this critical thing that I was able to read in MR&C. I was
expecting the same labels after a common statement. They *could be* the
same labels, but the interesting case is when they are not.
When they don't, I think ones sees something equivalent to an
equivalence-set-list.
Does the equivalence-set-list operate right to left?
>
> The extension is 49 storage units. z(50) would correspond
> to x(149). If you have bounds checking off it probably does.
>
> If you put
>
> real a
> common a(149)
>
> in another routine then a(149) would correspond to z(50) and the
> two common blocks would have the same length.
>
> -- glen
C:\MinGW\source>g95 common4.F90 -Wall -o f.exe
In file common4.F90:8
print x
1
Error: FORMAT tag at (1) must be a scalar integer variable
C:\MinGW\source>g95 common4.F90 -Wall -o f.exe
C:\MinGW\source>f
0 0 0 0 0 0 0 0 0 0
x is 333 333 333 333 333 333 333 333 333 333
y is 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
27 2
8 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
53 54
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
80 81
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
z is 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23
23 2
3 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23
23
heavens is 333 333 333 333 333 333 333 333 333 333 0 0 0 0 0 0 0 0 0 0 0
0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0
0 0 0 0 0
to_betsy is 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0
0 0 0 0 0 0 0
a is 333 333 333 333 333 333 333 333 333 333 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0
0 0
C:\MinGW\source>type common4.F90
implicit integer (h-t)
integer x(10),y(100),z(50)
common x
! equivalence (x,y),(y(100),z(1))
print *, x
x = 333
do i=1, 100
y(i)=i
enddo
z = 23
print *, "x is ", x
print *, "y is ", y
print *, "z is ", z
call sub
call sub2
contains
subroutine sub
common heavens(109),to_betsy(40)
print *, "heavens is ", heavens
print *, "to_betsy is ", to_betsy
end subroutine
subroutine sub2
integer a(149)
common a
print *, "a is ", a
end subroutine
endprogram
! g95 common4.F90 -Wall -o f.exe
C:\MinGW\source>
Are you certain that the extension isn't 139 storage units? Is there
possibly a difference between "extension" and "extent?"
--
larry gates
One operator is no big deal. That can be fixed in a jiffy.
-- Larry Wall in <1998091518...@wall.org>
Yes, COMMON blocks with different variable lists are effectively
like an EQUIVALENCE between the items that appear in the same
storage sequence spot in the different lists. It's a way to
rename storage or (in the good old days) reuse storage on a small
between different subroutines.
I once spent several days trying to debug a customer code that had
common /block/ .........,I,J,........
in a calling subroutine and
common /block/ .........,J,I,........
in the called subroutine
>
> Does the equivalence-set-list operate right to left?
Nope, it's all one big equivalent thing, there's no
order to the list. If a is equivalent to b, then b is
equivalent to a.
They are both loose words. Given the code
dimension x(10)
common x
you'd think the length or size or extent of the common block
was 10. When you add
dimension y(100)
equivalence (x,y)
the new length is 100. So, you've extended it by 90 to give it
an extent of 100. It would have been clearer to say the extension
is 139; but people usually talk about the length of the block,
not the length of part of the block that comes after some other
part.
Dick Hendrickson
> When they don't, I think ones sees something equivalent to an
> equivalence-set-list.
> Does the equivalence-set-list operate right to left?
My understanding is that there is no order to it. If you try
to EQUIVALENCE something where the order might matter then it
is illegal. You can't, for example:
INTEGER X(30),Y(10),Z(10)
EQUIVALENCE (X(10),Y(1)),(Y(10),Z(1)),(Z(10),X(1))
This attempts to EQUIVALENCE X(1) and X(28) which is illegal.
Reordering the sets, or the elements within a set, doesn't
change the equivalence. (As is usual for mathematical sets.)
-- glen
> It's because Z(1) is equivalenced to Y(100) in the main program.
> When you set z=23, you are also setting y(100) to 23. For some
> reason (;)) you've got a complicated set of equivalence here.
> It would be easier if you drew a picture or vertical histogram
> like
> x(1) y(1) heavens(1)
> x(2) y(2) heavens(2)
> ...
> x(10) y(10) heavens(10)
> ...
> y(100) z(1) heavens(100)
> ...
> Z(9) heavens(108)
> Z(10) heavens(109)
> z(11) to_betsy(1)
> ...
> z(50) to_betsy(49)
>
> and then tracer through what an assignment to any element does to
> the others.
>
> Dick Hendrickson
I'm more than halfway on this histogram, I wanted to know why a isn't
really working here:
C:\MinGW\source>g95 common6.F90 -Wall -o f.exe
C:\MinGW\source>f
x is 1 2 3 4 5 6 7 8 9 10
y is 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
27 2
8 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
53 54
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
80 81
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 23
z is 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23
23 2
3 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23
23
a is 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
index a x y z
1 0 1 1
2 0 2 2
3 0 3 3
4 0 4 4
5 0 5 5
6 0 6 6
7 0 7 7
8 0 8 8
9 0 9 9
10 0 10 10
11 0 11
12 0 12
13 0 13
14 0 14
...
96 0 96
97 0 97
98 0 98
99 0 99
C:\MinGW\source>type common6.F90
implicit integer (h-z)
integer x(10),y(100),z(50)
integer a
common a(149)
common x
equivalence (x,y),(y(100),z(1))
x = 333
do i=1, 100
y(i)=i
enddo
z = 23
print *, "x is ", x
print *, "y is ", y
print *, "z is ", z
print *, "a is ", a
print *, "index a x y z "
100 format (i6, i6 , i6, i6)
do i=1,10
print 100, i, a(i), x(i), y(i)
end do
101 format (i6, i6, 6x,i6)
do i=11,99
print 101, i, a(i), y(i)
end do
endprogram
! g95 common6.F90 -Wall -o f.exe
C:\MinGW\source>
--
larry gates
"We all agree on the necessity of compromise. We just can't agree on
when it's necessary to compromise."
-- Larry Wall in <1991Nov13.1...@netlabs.com>
It's because you've declared (listed)
the variables "a" and "x" in blank
common in the SAME PROGRAM UNIT. In
this case (same program unit), each
*common* statement appends to the
previous. So "a" appears sequentially
first in the common, followed by "x"
(and it's various equivalence members).
In Dick's example, the different names
for the variables in blank common were
(1) in the main program, and (2) in a
subroutine. Different program units.
BTW, the first time a saw more than
one (it was *many*) common statements
(in my case, a *named* common) in one
program unit (actually, an INCLUDE file),
I was puzzled to the extreme because I
didn't understand the issue of appending
the variables from each new common
statement with the previous ones. I
thought that a variety of definitions
was being given for overlapping
variables in the common, and that didn't
make sense programmatically. Of course,
that's not what is was doing, and that's
why the program worked! ;-}
-Ken
> On Sat, 21 Feb 2009 00:02:35 -0700, Glen Herrmannsfeldt wrote:
>
>> Larry Gates wrote:
>> (snip, I wrote)
>>
>>>>There is a very close association between COMMON and EQUIVALENCE.
>>
>>>>Some of this is in 5.5.2 in Fortran 2003.
>>
>>>>In 5.5.2.1: "Data objects associated with an entity in a common
>>>> block are considered to be in that common block."
>>
>>>>In 5.5.2.2: "The size of a common block is the size of its common
>>>> block storage sequence, including any extensions
>>>> of the sequence resulting from equivalence association."
>>
>>> implicit integer (h-t)
>>> integer x(10),y(100),z(50)
>>
>>> common x
>>> equivalence (x,y),(y(100),z(1))
>>
>>> By how much is the extension of x here?
>>
>> Well, the common block but not really x.
> Are you certain that the extension isn't 139 storage units? Is there
> possibly a difference between "extension" and "extent?"
Doesn't the common block start at ten units and end with 149?
--
larry gates
The stupid people are the ones proposing to outlaw stupidity. :-)
-- Larry Wall in <2005070803...@wall.org>
> On Feb 23, 4:35Â pm, Larry Gates <la...@example.invalid> wrote:
> [...]
> It's because you've declared (listed)
> the variables "a" and "x" in blank
> common in the SAME PROGRAM UNIT. In
> this case (same program unit), each
> *common* statement appends to the
> previous. So "a" appears sequentially
> first in the common, followed by "x"
> (and it's various equivalence members).
>
> In Dick's example, the different names
> for the variables in blank common were
> (1) in the main program, and (2) in a
> subroutine. Different program units.
Thanks for your response, Ken.
implicit integer (h-t)
integer x(10),y(100),z(50)
integer a
common a(149)
common x
equivalence (x,y),(y(100),z(1))
x = 333
do i=1, 100
y(i)=i
enddo
z = 23
print *, "x is ", x
print *, "y is ", y
print *, "z is ", z
call sub
call sub2
contains
subroutine sub
common heavens(109),to_betsy(40)
print *, "heavens is ", heavens
print *, "to_betsy is ", to_betsy
end subroutine
subroutine sub2
integer a(149)
common a
print *, "a is ", a
end subroutine
endprogram
! g95 common3.F90 -Wall -o f.exe
This has them in different program units. I'm curious if you can tell me
what the output is without *looking?*
>
> BTW, the first time a saw more than
> one (it was *many*) common statements
> (in my case, a *named* common) in one
> program unit (actually, an INCLUDE file),
> I was puzzled to the extreme because I
> didn't understand the issue of appending
> the variables from each new common
> statement with the previous ones. I
> thought that a variety of definitions
> was being given for overlapping
> variables in the common, and that didn't
> make sense programmatically. Of course,
> that's not what is was doing, and that's
> why the program worked! ;-}
>
> -Ken
I think we're talking about the same "aha" moment. I read it in MR&C in
§20.2.3. It's the contrast between the fourth and fifth common statements
in that chapter.
What, out of curiosity, did that include file look like?
--
larry gates
There's some entertainment value in watching people juggle nitroglycerin.
-- Larry Wall in <1997120417...@wall.org>
Since I can only access a Fortran compiler at home
on the weekends *when* I'm not engaged in a honey-do
project, :-) I'll have to do this by "visual inspection".
Firstly, I don't see any initialization for the array
"a", but I seem to recall that your compiler, with the
options you're using, initializes it to integer zero.
(Your program is non-conforming because "a" is undefined,
right?)
Next, in the main program, (blank) common will consist
of the array "a", 149 integers long, followed by the
array "x", for ten more integers.
Blank common will then be "extended" through the
equivalence between "x" and "y" to 149 + 100 integers.
But the subsequent equivalence between y(100) and z(1)
adds yet another 49 integers (only 49, not 50, because
"z" overlaps the last location of "y"). That gives
149+100+49 = 298 integers in the main program.
The statement x = 333 will set x(1:10) *and* y(1:10)
to 333. However, the subsequent loop sets y(i) = i,
but also x(i) = i (through the equivalence).
Finally, the statement z = 23 will set z(1:50) to 23,
but also y(100) = 23, again through the equivalence.
So blank common will consist of 149 zeros (or other
uninitialized values), followed by 99 integers whose
values are 1 to 99, followed by 50 "23"s.
In the call to "sub", the first print statement will
output 109 zeros, the second 40 zeros.
In "sub2", the print statement will again print 149
zeros.
All clear now? :-)
-Ken
After my reply yesterday, I thought I'd
make another couple of suggestions.
First, try modifying your code to reverse
the order of assignments to x, y and x.
Second, add another array to common in
"sub" (extending common to match its length
in the main program).
Third, in "sub2" declare the array "a" to
be of length 298.
>
> implicit integer (h-t)
> integer x(10),y(100),z(50)
> Â Â Â Â integer a
! Â Â Â Â common a(149)
> Â common x
> Â equivalence (x,y),(y(100),z(1))
>
z = 23
do i = 1, 100
y(i) = i
enddo
x = 333
>! x = 333
>!
>! do i=1, 100
>! y(i)=i
>! enddo
>!
>! Â Â Â z = 23
>
> Â print *, "x is ", x
> Â print *, "y is ", y
> Â print *, "z is ", z
>
> call sub
> call sub2
>
> Â contains
> Â Â Â subroutine sub
common heavens(109),to_betsy(40),my_dear(149)
> Â Â Â print *, "heavens is ", heavens
> Â Â Â print *, "to_betsy is ", to_betsy
print *, "my_dear is ", my_dear
> Â Â Â end subroutine
>
> Â Â Â subroutine sub2
integer a(298)
> Â Â Â Â common a
>
> print *, "a is ", a
> Â Â Â end subroutine
>
> Â endprogram
>
> ! g95 common3.F90 -Wall -o f.exe
[...]
Now you tell us if you can make sense of
the output.
> What, out of curiosity, did that include file look like?
I forgot to answer this question yesterday.
First, when I use the term "include file",
I always mean a file used with the Fortran
INCLUDE statement. That is, it is *just*
Fortran source code that gets inserted,
wholesale without change, at the point
where the INCLUDE statement occurs. I'm
emphasizing this point to make it clear
I am *not* talking about C-style header
files *not* any preprocessing that might
imply.
Second, the discussion we've been having
up to now has been about the oldest form
of COMMON, so-called "blank COMMON".
I believe since at least f66 (or for sure,
since IBM's FORTRAN H) *named* common has
been available, which allows some modicum
of control over the shared storage areas.
I.e., you don't have to dump absolutely
*everything* into one COMMON. The syntax
for a named common is:
COMMON /some_name/ var1, var2,...
So the INCLUDE file I was dealing with
used named commons (under f77).
To give just an idea of what it looked
like (and I'll suppress all the comments
that would go along with the declarations,
etc.), you might have:
INTEGER*2 BUFFER(2048)
COMMON /CAMAC/ BUFFER
...
INTEGER*4 IOSTAT,IOCNT,BUFLEN
COMMON /CAMAC/ IOSTAT,IOCNT,BUFLEN
...
REAL*4 WIRELOC(123)
COMMON /CAMAC/ WIRELOC
...
You get the idea. I think there was
some discipline to declare only a single
named COMMON per include file, often with
any given subroutine INCLUDE'ing many
of these files in order to access the
many different named COMMONs.
I've spewed enough, already! Hope this helps.
-Ken
Sorry to follow-up my own post, but
on reading it, I see I changed my mind
mid-edit. Sigh.
> > implicit integer (h-t)
> > integer x(10),y(100),z(50)
> > Â Â Â Â integer a
> ! Â Â Â Â common a(149)
I had commented-out this first statement
for COMMON A(129). Leave it active for
my suggestions to make any (or as much)
sense.
[...]
-Ken
Thanks, Ken, it takes me a bit to work through these suggestions. It
sounds like you're on the money, though.
--
larry gates
My arthritic pinkies are already starting to ache just thinking about
||||=.
-- Larry Wall in <1998092516...@wall.org>
I don't have time tonight to get very far with this.
Here's my Big Question right now.
implicit integer (a-t)
integer x(10),y(100),z(50)
common x
equivalence (x,y),(y(100),z(1))
x = 333
do i=1, 100
y(i)=i
enddo
z = 23
print *, "x is ", x
print *, "y is ", y
print *, "z is ", z
call sub
call sub2
contains
subroutine sub
common heavens(109),to_betsy(40)
print *, "heavens is ", heavens
print *, "to_betsy is ", to_betsy
end subroutine
subroutine sub2
integer a(37)
common a
print *, "a is ", a
end subroutine
endprogram
! g95 common7.F90 -Wall -o f.exe
I can't compile this right now, because I have a working gfortran
installation. (Ergo g95 is on the fritz.)
Why doesn't a share the same first ten integers that x and y do?
Is the common block ten places when it is called into existence?
Main extends this to 149. When you call the subroutine, doesn't a start
with the beginning of the common block?
Playing poker tonight, woo-hoo. Cheers
>
> Blank common will then be "extended" through the
> equivalence between "x" and "y" to 149 + 100 integers.
> But the subsequent equivalence between y(100) and z(1)
> adds yet another 49 integers (only 49, not 50, because
> "z" overlaps the last location of "y"). That gives
> 149+100+49 = 298 integers in the main program.
>
> The statement x = 333 will set x(1:10) *and* y(1:10)
> to 333. However, the subsequent loop sets y(i) = i,
> but also x(i) = i (through the equivalence).
>
> Finally, the statement z = 23 will set z(1:50) to 23,
> but also y(100) = 23, again through the equivalence.
>
> So blank common will consist of 149 zeros (or other
> uninitialized values), followed by 99 integers whose
> values are 1 to 99, followed by 50 "23"s.
>
> In the call to "sub", the first print statement will
> output 109 zeros, the second 40 zeros.
>
> In "sub2", the print statement will again print 149
> zeros.
>
> All clear now? :-)
>
> -Ken
--
larry gates
To ordinary folks, conversion is not always automatic. It's something
that may or may not require explicit assistance. See Billy Graham. :-)
-- Larry Wall in <1997101417...@wall.org>
You've got two similar versions of the program above, maybe
you should trim out one of them. It's possible I'm answering
the correct question about the wrong program. ;)
In the second version, it looks to me like it does. Why
do you think it doesn't? It doesn't in the first example.
>
> Is the common block ten places when it is called into existence?
Sort of, but that's not the way I look at it. I tend to think
of all the declaratives as one big group. It almost never
matters which order you put the declarations in; so I usually
look at them as a group. Then the common/equivalence in
the main program declares a blank common block of length 149.
I wouldn't say "called into existence"; that, to me, implies that
the declaration in the main program is, somehow, more better
than the others. It really isn't. There are rules for
how common blocks can/must be declared in different procedures;
but one declaration isn't the master one.
>
> Main extends this to 149. When you call the subroutine, doesn't a start
> with the beginning of the common block?
I think so, again why don't you think so?
Dick Hendrickson
> Larry Gates wrote:
>> On Wed, 25 Feb 2009 14:55:29 -0800 (PST), ken.fa...@gmail.com wrote:
> You've got two similar versions of the program above, maybe
> you should trim out one of them. It's possible I'm answering
> the correct question about the wrong program. ;)
>
> In the second version, it looks to me like it does. Why
> do you think it doesn't? It doesn't in the first example.
This is my eighth version of this program, not counting mistakes. Keeping
the revisions separate on one's computer and for commenting on usenet is
wearing an editor's hat that tends to fit poorly on the writer.
>
>>
>> Is the common block ten places when it is called into existence?
>
> Sort of, but that's not the way I look at it. I tend to think
> of all the declaratives as one big group. It almost never
> matters which order you put the declarations in; so I usually
> look at them as a group. Then the common/equivalence in
> the main program declares a blank common block of length 149.
>
> I wouldn't say "called into existence"; that, to me, implies that
> the declaration in the main program is, somehow, more better
> than the others. It really isn't. There are rules for
> how common blocks can/must be declared in different procedures;
> but one declaration isn't the master one.
>
>>
>> Main extends this to 149. When you call the subroutine, doesn't a start
>> with the beginning of the common block?
>
> I think so, again why don't you think so?
>
> Dick Hendrickson
I just ran this with silverfrost and remember why I liked this compiler so
much. Here is the output:
x is 1 2 3 4 5
6
7 8 9
10
y is 1 2 3 4 5
6
7 8 9
10 11 12 13 14 15
16 17 18
19 20 21 22 23 24
25 26 27
28 29 30 31 32 33
34 35 36
37 38 39 40 41 42
43 44 45
46 47 48 49 50 51
52 53 54
55 56 57 58 59 60
61 62 63
64 65 66 67 68 69
70 71 72
73 74 75 76 77 78
79 80 81
82 83 84 85 86 87
88 89 90
91 92 93 94 95 96
97 98 99
23
z is 23 23 23 23 23
23
23 23 23
23 23 23 23 23 23
23 23 23
23 23 23 23 23 23
23 23 23
23 23 23 23 23 23
23 23 23
23 23 23 23 23 23
23 23 23
23 23 23 23 23
heavens is 1 2 3 4 5
6 7 8
9 10 11 12 13 14
15 16 17
18 19 20 21 22 23
24 25 26
27 28 29 30 31 32
33 34 35
36 37 38 39 40 41
42 43 44
45 46 47 48 49 50
51 52 53
54 55 56 57 58 59
60 61 62
63 64 65 66 67 68
69 70 71
72 73 74 75 76 77
78 79 80
81 82 83 84 85 86
87 88 89
90 91 92 93 94 95
96 97 98
99 23 23 23 23 23
23 23 23
23 23
to_betsy is 23 23 23 23 23
23 23 23
23 23 23 23 23 23
23 23 23
23 23 23 23 23 23
23 23 23
23 23 23 23 23 23
23 23 23
23 23 23 23 23
a is 1 2 3 4 5
6
7 8 9
10 11 12 13 14 15
16 17 18
19 20 21 22 23 24
25 26 27
28 29 30 31 32 33
34 35 36
37
Press RETURN to close window . . .
Here is the the source:
x = 333
call sub
call sub2
endprogram
! silverfrost's comments:
Compiling and linking file: FreeFormat1.f95
WARNING - Common block "//" was previously defined as size 40 but is now
defined as size 152
WARNING - Common block "//" was previously defined as size 40 but is now
defined as size 600
Creating executable: C:\Documents and Settings\dan\My
Documents\FreeFormat1.EXE
What is silverfrost saying here? Default ints are size 4.
--
larry gates
They can always run stderr through uniq. :-)
-- Larry Wall in <1997040123...@wall.org>
> What is silverfrost saying here? ...
Exactly what you did -- you put x into COMMON, then equivalenced other
arrays to it that are larger in extent; hence extending the COMMON size.
I fail to see what's such an issue you're having here...
Start w/ a common point and simply lay out the memory linearly from
there on a grid of one line (or column) for each variable and look at
the overall alignment(s).
--
> Larry Gates wrote:
> ...
>> integer x(10),y(100),z(50)
>> common x
>> equivalence (x,y),(y(100),z(1))
> ...
>> Compiling and linking file: FreeFormat1.f95
>> WARNING - Common block "//" was previously defined as size 40 but is now
>> defined as size 152
>> WARNING - Common block "//" was previously defined as size 40 but is now
>> defined as size 600
> ...
>
>> What is silverfrost saying here? ...
>
> Exactly what you did -- you put x into COMMON, then equivalenced other
> arrays to it that are larger in extent; hence extending the COMMON size.
>
> I fail to see what's such an issue you're having here...
>
The size that others talked about for this was 149, and that was before
this:
subroutine sub2
integer a(37)
common a
print *, "a is ", a
end subroutine
I see nothing in silverfrost's warning that makes sense in the face of the
above routine.
> Start w/ a common point and simply lay out the memory linearly from
> there on a grid of one line (or column) for each variable and look at
> the overall alignment(s).
Do I add 37 boxes to the common block with the above routine?
--
larry gates
It's not really a rule--it's more like a trend.
-- Larry Wall in <1997102217...@wall.org>
Yes, you didn't equivalence it to overlay it over any existing memory so
it's additional to what else was already in blank common including that
associated w/ common via the equivalence.
And of course, there's more buried in subroutine sub along w/ this as well.
I frankly don't care enough to sit down and actually do it, but I'm
quite comfortable that Silverfrost kept up w/ the total size required
for blank common despite the foolishness of the code and that if you
would make up the map it would explain all.
Of course, it's quite likely there's some switch in the compiler/linker
to generate memory maps for you.
--
> Of course, it's quite likely there's some switch in the compiler/linker
> to generate memory maps for you.
I believe this is how I first learned about how COMMON and EQUIVALENCE
work together. The OS/360 compilers print maps of the offsets of
the variables in the block, for each one, and the length of that block.
It might be that some still generate such maps, but they
are much less common than they used to be.
-- glen
That is, unfortunately, far too true... :(
But, it hardly seems worthwhile to keep beating this horse here when
it's a case of simply working through as set of relative addresses which
can be done either manually or perhaps through the compiler/linker.
Of course, judicious use of the LOC() extension which most compilers
have in some incarnation could be used as well if all else fails it
would seem....
--
It doesn't seem like it should be all that hard.
>
> But, it hardly seems worthwhile to keep beating this horse here when
> it's a case of simply working through as set of relative addresses which
> can be done either manually or perhaps through the compiler/linker.
>
> Of course, judicious use of the LOC() extension which most compilers
> have in some incarnation could be used as well if all else fails it
> would seem....
>
> --
--
Gary Scott
mailto:garylscott@sbcglobal dot net
Fortran Library: http://www.fortranlib.com
Support the Original G95 Project: http://www.g95.org
-OR-
Support the GNU GFortran Project: http://gcc.gnu.org/fortran/index.html
If you want to do the impossible, don't hire an expert because he knows
it can't be done.
-- Henry Ford
CVF does have /map but I didn't run a sample case to see what it would
actually output for the posited code.
One thing I miss is the cross-reference map that CDC FTN compilers
generated. W/ IMPLICIT NONE and other niceties some of the reasons are
somewhat lessened, but it was surely useful in its day w/ as compared to
those w/o it.
--
Well, /map doesn't really help in CVF unless there's a way to force
additional output or I'm not interpreting it correctly. It shows all
entry points but not the data sections afaict.
The /list option helps some -- altho I didn't spend enough time to
actually dig thru it in detail it looks like it would be possible to
ferret out the mapping from it.
Superficially, it appears CVF thinks the extended blank common size is
596 bytes, not 600, though.
--
Dick Hendrickson
Well, actually, no...I did the following in Excel for simplicity and
trimmed it down. The repeat of the blank common in the two subroutines
overlays the variables there into the beginning of the same common area
as that defined in the main program. The overall size is still 149; the
warnings come from the extended size from that in the main program.
For brevity I've elided middles of arrays, the names are truncated to
first letters.
x y z h t a
1 1 1 1
2 2 2 2
3 3 3 3
4 4 4 4
5 5 5 5
6 6 6 6
7 7 7 7
8 8 8 8
9 9 9 9
10 10 10 10
11 11 11
... ... ...
35 35 35
36 36 36
37 37 37
38 38
... ...
97 97
98 98
99 99
100 1 100
2 101
3 102
... ...
19 108
20 109
21 1
22 2
23 3
... ...
48 28
49 29
50 30
31
32
33
34
35
36
37
38
39
40
Can we let this rest now?
--
>> Compiling and linking file: FreeFormat1.f95
>> WARNING - Common block "//" was previously defined as size 40 but is now
>> defined as size 152
>> WARNING - Common block "//" was previously defined as size 40 but is now
>> defined as size 600
>> Creating executable: C:\Documents and Settings\dan\My
>> Documents\FreeFormat1.EXE
>>
>> What is silverfrost saying here? Default ints are size 4.
>>
> From what you show, it's hard to say. You are "defining" the
> common block in several places and [what you show of] the
> warnings don't point to a specific thing. The initial
> common might have a length of 40 = 4*10. I'd guess the
> warning are about the two equivalence sets extending
> blank common. Try taking out the two contained
> subroutines and see what messages you get. Then, try
> uncontaining the subroutines. I don't think there is any
> reason for having them as internal subroutines. maybe then
> you'll understand the messages.
>
> Dick Hendrickson
Alles klar, Herr Kommissar.
Compiling and linking file: FreeFormat2.f95
WARNING - Common block "//" was previously defined as size 40 but is now
defined as size 600
WARNING - Common block "//" was previously defined as size 40 but is now
defined as size 152
Creating executable: C:\Documents and Settings\dan\My
Documents\FreeFormat2.EXE
! silverfrost
implicit integer (a-z)
integer x(10),y(100),z(50)
common x
equivalence (x,y),(y(100),z(1))
x = 33
do i=1, 100
y(i)=i
enddo
z = 23
print *, "x is ", x
print *, "y is ", y
print *, "z is ", z
call sub
call sub2
endprogram
! silverfrost
subroutine sub
common heavens(109),to_betsy(40)
print *, "heavens is ", heavens
print *, "to_betsy is ", to_betsy
end subroutine
subroutine sub2
integer a(37)
common a
print *, "a is ", a
end subroutine
--
larry gates
Python's syntax succeeds in combining the mistakes of Lisp and Fortran.
I do not contrue that as progress.
-- Larry Wall in <2004051216...@wall.org>
Yup.
--
larry gates
stab_val(stab)->str_nok = 1; /* what a wonderful hack! */
-- Larry Wall in stab.c from the perl source code
Actually, it didn't dawn on me until later there is one thing I don't
follow in the Silverfrost warnings -- perhaps that was your point of
confusion as well and I misinterpreted the question raised.
The size of the extended blank common is given as "size 40 but is now
defined as size 152" and likewise as "now 600".
It seems as though an extra position has shown up as the allocated
arrays were 37 and the total of 149 which translate to 148 and 596,
respectively.
The location of the first member of those arrays might be of interest to
look at--if there were anything suspicious in the Silverfrost
implementation that's where it would seem to be.
CVF as noted, came back w/ the expected 148 and 596.
Most likely there's no real error but it's possible there's some
overhead/alignment issue owing to the attempt to confound (I presume)
the compiler.
_IF_ you can demonstrate the alignment/accession of the various arrays
isn't as the spreadsheet indicates, then there is a problem. I'd assume
unless shown differently, that the actual references in code will be ok.
--
>>> Can we let this rest now?
>>
>> Yup.
>
> Actually, it didn't dawn on me until later there is one thing I don't
> follow in the Silverfrost warnings -- perhaps that was your point of
> confusion as well and I misinterpreted the question raised.
>
> The size of the extended blank common is given as "size 40 but is now
> defined as size 152" and likewise as "now 600".
>
> It seems as though an extra position has shown up as the allocated
> arrays were 37 and the total of 149 which translate to 148 and 596,
> respectively.
>
> The location of the first member of those arrays might be of interest to
> look at--if there were anything suspicious in the Silverfrost
> implementation that's where it would seem to be.
>
> CVF as noted, came back w/ the expected 148 and 596.
>
> Most likely there's no real error but it's possible there's some
> overhead/alignment issue owing to the attempt to confound (I presume)
> the compiler.
>
> _IF_ you can demonstrate the alignment/accession of the various arrays
> isn't as the spreadsheet indicates, then there is a problem. I'd assume
> unless shown differently, that the actual references in code will be ok.
Is there a way for a subroutine to query how large the common block is upon
initialization? Then one could write a routine that would the dump the
common block to stdout.
I could see that the numbers were (n+1)*4, which was one part of the
problem. Somehow, with common, equivalence and extensions, I didn't get
any of it until I got all of it, like a roof doesn't keep out the rain
until the whole thing's covered.
Thanks for your help. I'm gonna keep this thread for when guys younger
than me stumble on the same thing.
MR&C had a very good chapter here, 20.2.3. I wouldn't mind having your
spreadsheet program, if you feel like sending it.
--
larry gates
As with all the other proposals, it's basically just a list of words.
You can deal with that... :-)
-- Larry Wall in <1997090323...@wall.org>
No, not in the way you mean to ask. The sizes of each named
common block must be the same in each subprogram, so any
dumper routine can merely dump what is listed in the
COMMON /your name here/ list...
list.
For historical reasons, the length of blank common can be
different in different routines. But, again the routine
has all of it's own declarations in it and can easily
dump out whatever it's view of blank common is. If a
routine has something like
subroutine dump-common(n)
common x(40)
print *, (x(i), i=1,n)
print *, x
it is a programming error if N > 40. The second print will
dump out exactly 40 values. There is
no requirement that the first declaration of blank common
be the biggest or best.
Dick Hendrickson
As far as the subprogram(s) know, the arrays are the dimensions shown
locally; they don't know the overall size of common that they might just
happen to reside in--only the linker sees all. Trying to access beyond
the local array bounds to the rest of the common block not included in
the subroutine will (rightfully) give you a bounds error w/ checking on
and undefined behavior if you were to not use runtime checking that most
likely would show the expected values in areas that had had valid data
earlier but if it didn't you couldn't use that as any demonstration of a
problem as it would be illegal code to do so.
In your case, since you placed blank common in each routine, the first
variable in blank common in the routine begins at the beginning of blank
common--each is known by a different variable name locally, but the
memory association determines that each is really overlaid upon each
other in the sequence listed.
Hence, the LOC() function (an extension but virtually any compiler I'm
aware of has an implementation by some moniker) should show the same
memory location for the corresponding element of each of these. That is
what I mean earlier--I would be quite surprised if that didn't turn out
to be so; I suspect that whatever problem there is may be as trivial as
an "off by one" in just the warning computation of using a zero-based
calculation there instead of one-based. Of course, there could be some
alignment issue internally to the compiler/linker, but I'd be surprised
if the actual values you see from Standard-conforming Fortran to
demonstrate an access problem. If it did, that would indeed be a bug to
be fixed but seems so fundamental it's hard to imagine such an animal
wouldn't have been uncovered (and fixed) long ago.
The warning message size would seem to be worth a question to the
vendor's support--as noted, unless you can show a problem in a
functioning program within legal Fortran it wouldn't be a real bug but
certainly could be seen as an implementation issue.
> ... I wouldn't mind having your spreadsheet program, ...
There is no "program", I simply used the "fill series" edit function to
make a table of the array indices as the variables were added to blank
common and equivalenced in each program unit. There's really nothing
complicated about it; the first variable in each subprogram in a given
common block (named or unnamed) begins at the beginning of the given
block and extends as far as it is defined within the program unit.
Within a program unit additional COMMON statements add subsequently onto
the block in question; across program units it begins all over at the
beginning. Whatever the variable names are between the program units
are immaterial except in their ordering.
--
Your program reduced to the minimum including the shorter names...
implicit integer (a-t)
integer x(10),y(100),z(50)
common x
equivalence (x,y),(y(100),z(1))
write(*,*) 'Location X(1) ', %LOC(x(1))
call sub
call sub2
contains
subroutine sub
common h(109),t(40)
write(*,*) 'Location H(1) ', %LOC(h(1))
end subroutine
subroutine sub2
integer a(37)
common a
write(*,*) 'Location A(1) ', %LOC(a(1))
end subroutine
end program
C:\Temp> df /nologo dumcom.f90
dumcom.f90
C:\Temp> dumcom
Location X(1) 4438976
Location H(1) 4438976
Location A(1) 4438976
If Silverfrost doesn't have similar result, it's broken.
--
implicit integer (a-t)
integer x(10),y(100),z(50)
common x
equivalence (x,y),(y(100),z(1))
write(*,'(A,Z8)') 'Location X(1) ', %LOC(x(1))
call sub
call sub2
write(*,'(A,Z8)') 'Location X(1) ', %LOC(x(1))
contains
subroutine sub
common h(109),t(40)
write(*,'(A,Z8)') 'Location H(1) ', %LOC(h(1))
end subroutine
subroutine sub2
integer a(37)
common a
write(*,'(A,Z8)') 'Location A(1) ', %LOC(a(1))
end subroutine
end program
C:\Temp> df /nologo dumcom.f90
dumcom.f90
C:\Temp> dumcom
Location X(1) 43DBC0
Location H(1) 43DBC0
Location A(1) 43DBC0
Location X(1) 43DBC0
> write(*,'(A,Z8)') 'Location X(1) ', %LOC(x(1))
Silverfrost complains here.
C:\Documents and Settings\dan\My Documents\FreeFormat3.F95(7) : error 441 -
Illegal character combination, ',' followed by '%'
I thought you wanted to put this discussion to an end.
--
larry gates
Well, some of that relates to the fact that last year I basically
had to take half a year off to participate in various non-optional
gastric revisions.
-- Larry Wall in <20040226192...@wall.org>
Find it's incarnation of LOC() -- it probably is LOC() w/o the %.
> I thought you wanted to put this discussion to an end.
I was just trying to complete your question.
--
> Larry Gates wrote:
>> On Mon, 02 Mar 2009 20:05:35 -0600, dpb wrote:
>>
>>> write(*,'(A,Z8)') 'Location X(1) ', %LOC(x(1))
>>
>> Silverfrost complains here.
>
> Find it's incarnation of LOC() -- it probably is LOC() w/o the %.
That works, but what is loc()?
Location X(1) 40204C
Location H(1) 40204C
Location A(1) 40204C
Location X(1) 40204C
Press RETURN to close window . . .
--
larry gates
Just don't make the '9' format pack/unpack numbers... :-)
-- Larry Wall in <1997100914...@wall.org>
<http://www.silverfrost.com/23/ftn95/support/documentation.aspx>
--
> Larry Gates wrote:
>> On Tue, 03 Mar 2009 08:33:21 -0600, dpb wrote:
>>
>>> Larry Gates wrote:
>>>> On Mon, 02 Mar 2009 20:05:35 -0600, dpb wrote:
>>>>
>>>>> write(*,'(A,Z8)') 'Location X(1) ', %LOC(x(1))
>>>> Silverfrost complains here.
>>> Find it's incarnation of LOC() -- it probably is LOC() w/o the %.
>>
>> That works, but what is loc()?
>
> <http://www.silverfrost.com/23/ftn95/support/documentation.aspx>
implicit integer (a-t)
integer x(10),y(100),z(50)
common x
equivalence (x,y),(y(100),z(1))
write(*,'(A,Z8)') 'Location X(1) ', LOC(x(1))
call sub
call sub2
write(*,'(A,Z8)') 'Location X(1) ', LOC(x(1))
contains
subroutine sub
common h(109),t(40)
write(*,'(A,Z8)') 'Location H(1) ', LOC(h(1))
end subroutine
subroutine sub2
integer a(37)
common a
write(*,'(A,Z8)') 'Location A(1) ', LOC(a(1))
end subroutine
end program
! gfortran loc1.f90 -o out
I looked for loc in the silverfrost documentation and couldn't find
anything. As much as I like it for anything it can handle, I don't think
anyone's home there.
I ran the same code with gfortran, and I got the same result, namely that
all of the storage begins in the same place. From gfortran.pdf:
To get the address of elements, this extension provides an intrinsic
function LOC(). The
LOC() function is equivalent to the & operator in C, except the address is
cast to an integer
type.
Are C pointers and Cray pointers the same thing?
--
larry gates
I'm not consistent about consistency, you see, except when I am...
And I try to believe six foolish consistencies before breakfast each day.
:-)
-- Larry Wall in <20050307164...@wall.org>
> Are C pointers and Cray pointers the same thing?
No.
--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
> Larry Gates <la...@example.invalid> wrote:
>
>> Are C pointers and Cray pointers the same thing?
>
> No.
I find the documentation with gfortran.pdf, at least prima facie, good in
this respect:
5.1.13 Cray pointers
Cray pointers are part of a non-standard extension that provides a C-like
pointer in Fortran.
...
Cray pointers are just ordinary integers, so the user is responsible for
determining
how many bytes to add to a pointer in order to increment it. Consider the
following example:
real target(10)
real pointee(10)
pointer (ipt, pointee)
ipt = loc (target)
ipt = ipt + 1
Let me rephrase. Are C pointers that have been caste as ints analogous to
Cray pointers in fortran?
--
larry gates
Randal said it would be tough to do in sed. He didn't say he didn't
understand sed. Randal understands sed quite well. Which is why he
uses Perl. :-) -- Larry Wall in <78...@jpl-devvax.JPL.NASA.GOV>
The answer remains "no".
Regards,
Nick Maclaren.
> On Wed, 4 Mar 2009 22:47:41 -0800, Richard Maine wrote:
>
>> Larry Gates <la...@example.invalid> wrote:
>>
>>> Are C pointers and Cray pointers the same thing?
>>
>> No.
>
> I find the documentation with gfortran.pdf, at least prima facie, good in
> this respect:
>
> 5.1.13 Cray pointers
> Cray pointers are part of a non-standard extension that provides a C-like
> pointer in Fortran.
>
> ...
>
> Cray pointers are just ordinary integers, so the user is responsible for
> determining
> how many bytes to add to a pointer in order to increment it. Consider the
> following example:
> real target(10)
> real pointee(10)
> pointer (ipt, pointee)
> ipt = loc (target)
> ipt = ipt + 1
>
>
> Let me rephrase. Are C pointers that have been caste as ints analogous to
> Cray pointers in fortran?
Do you want an answer 1. in general or 2. for a specific version of a
specific compiler under a specific version of the specific operating system?
You got the answer to 1 but failed to provide enough information for 2 which
would be in the specific manual in any case.