On 1/25/2023 9:24 PM, Arne Vajhøj wrote:
> On 1/25/2023 8:36 PM, Dave Froble wrote:
>> On 1/25/2023 6:50 PM, Arne Vajhøj wrote:
>>> On 1/25/2023 5:55 PM, John Reagan wrote:
>>>> Here's a nasty Fortran program where each subroutine initializes and
>>>> reinitializes parts of the
>>>> same common block in a particular order.
>>>>
>>>> subroutine print_common
>>>> common /mypsect/ i1,i2
>>>> integer*4 :: i1,i2
>>>> write (*,10) i1,i2
>>>> 10 format (' ',Z8,' ',Z8)
>>>> return
>>>> end
>>>>
>>>> subroutine update_longwords
>>>> common /mypsect/ i1,i2
>>>> c start with putting hex AAAAAAAA into both longwords
>>>> integer*4 :: i1='AAAAAAAA'X,i2='AAAAAAAA'X
>>>> return
>>>> end
>>>>
>>>> subroutine update_words
>>>> c and update bottom words with BBBB
>>>> common /mypsect/ w1,w2,w3,w4
>>>> integer*2 :: w1,w2='BBBB'X,w3,w4='BBBB'X
>>>> return
>>>> end
>>>>
>>>> subroutine update_bytes
>>>> c and update bottom bytes with CC
>>>> common /mypsect/ b1,b2,b3,b4,b5,b6,b7,b8
>>>> integer*1 :: b1,b2,b3,b4='CC'X,b5,b6,b7,b8='CC'X
>>>> return
>>>> end
>>>>
>>>> program main
>>>> c by now, the two longwords in the common should be
>>>> c CCBBAAAA CCBBAAAA
>>>> call print_common
>>>> end
>>>
>>> That is horrible code IMHO.
>>
>> I find that an interesting comment ...
>>
>> Perhaps it is doing what someone needed it to do ...
>
> I don't think they did for fun.
>
> But I believe there are better ways to do that.
>
>>> Initializing the same common block in multiple subroutines
>>> is not something I would ever do.
>>
>> You've never redefined the data type of some data?
>
>> Consider:
>>
>> Record TLS
>> Variant
>> Case
>> String Rec$=42
>> Case
>> Byte Byte1%
>> Byte VerMajor%
>> Byte VerMinor%
>> Long UnixDate%
>> String Random$=28
>> Long SessionID%
>> Word Cypher%
>> Byte Method%
>> End Variant
>> End Record
>>
>>
>> In this case the Basic RECORD statement allows multiple variants of the same
>> memory, basically allowing different types of variables to be used on the same
>> memory location(s). Useful, and a relatively later addition to the language.
>> Similar to what is called a structure in C and perhaps other languages.
>
> That is really a different thing than initializing the same psect
> multiple times in different places.
>
> Having to overlay different types is a common feature in languages.
> Pascal got the variant case record similar to the Basic code above.
> C got union. In Fortran it can be achieved using common blocks, but
> the right way (IMHO) is to use equivalence.
>
>> Perhaps some would not want variants, but I for one have used them many times.
>>
>> Map (D) Long D1%
>> Map (D) String D1$=4
>>
>> Now in a MAP statement, whiich is rather similar to a COMMON block, multiple
>> definitions of the MAP statement allows for a similar redefinition of the same
>> memory. In the above, a longword value is stored in 4 bytes of memory. The
>> redefinition of the MAP statement allows the same memory to be labeled as a
>> string or a longword.
>>
>> It's been useful to me in the past.
>
> I am not arguing against this.
>
> But in Fortran this should not be done using common blocks but
> via equivalence.
>
> integer*4 iv
> character*4 sv
> equivalence (iv,sv)
>
> It has local scope and is readable.
>
> And if necessary it can be combined with a common block.
>
> In extremely rare cases there may even be a good reason to
> have different definition (different types) in different routines.
> It is difficult to read as there are no indication in the
> individual routine that it has a different definition elsewhere.
> But one never knows what can be required to solve a problem.
>
> But I can not believe there are any cases where I would
> consider it good to static initialize parts of a common
> block in different routines.
>
> Arne
>
I will admit that my normal practice is to have any such declarations in one
place, and include the same definition is each subroutine that uses it. Of
course, if it is modified, one must re-compile all routines that include it.
:-)
I can be a little dense, but I fail to see the problem in John's example. If I
understand it correctly, each routine defines the same PSECT (I believe each
common block has it's own PSECT, a Basic MAP statement I'm rather sure does so)
with a different definition. So what? And yes, it might be confusing to some.
Then again, it's been over 40 years since I did any Fortran.
And that brings this question. What does:
integer*2 :: w1,w2='BBBB'X,w3,w4='BBBB'X
do?
Does both w1 and w2 get set to BBBB? That is not what the comments indicate?
--
David Froble Tel: 724-529-0450
Dave Froble Enterprises, Inc. E-Mail: ***@tsoft-inc.com
DFE Ultralights, Inc.
170 Grimplin Road
Vanderbilt, PA 15486