I need many of my integers to be integer*8 in my port to 64 bit. In
C/C++ code, I can say 123456L to mean a long long value, generally 64
bit. Is there a corresponding way to do this in Fortran ...
On Tue, 1 Oct 2024 21:58:40 -0500, Lynn McGuire wrote:
I need many of my integers to be integer*8 in my port to 64 bit. In
C/C++ code, I can say 123456L to mean a long long value, generally 64
bit. Is there a corresponding way to do this in Fortran ...
integer(kind = 8), parameter :: bigval = 9223372036854775807_8
print *, bigval
prints
9223372036854775807
I will have to put _8 in about 100,000 lines of
my F77 code.
On 10/2/2024 2:00 AM, Lawrence D'Oliveiro wrote:
On Tue, 1 Oct 2024 21:58:40 -0500, Lynn McGuire wrote:
I need many of my integers to be integer*8 in my port to 64 bit. In
C/C++ code, I can say 123456L to mean a long long value, generally 64
bit. Is there a corresponding way to do this in Fortran ...
integer(kind = 8), parameter :: bigval = 9223372036854775807_8
print *, bigval
prints
9223372036854775807
Thanks !
I was afraid of that. I will have to put _8 in about 100,000 lines of
my F77 code. And the future conversion to C++ will need special handling.
On Wed, 02 Oct 2024 14:30:48 -0500, Lynn McGuire wrote:
On 10/2/2024 2:00 AM, Lawrence D'Oliveiro wrote:
On Tue, 1 Oct 2024 21:58:40 -0500, Lynn McGuire wrote:
I need many of my integers to be integer*8 in my port to 64 bit. In
C/C++ code, I can say 123456L to mean a long long value, generally 64
bit. Is there a corresponding way to do this in Fortran ...
integer(kind = 8), parameter :: bigval = 9223372036854775807_8
print *, bigval
prints
9223372036854775807
Thanks !
I was afraid of that. I will have to put _8 in about 100,000 lines of
my F77 code. And the future conversion to C++ will need special handling. >>
If you 100,000 lines of C++ without a trailing 'L', you would
need to add 'L' to get a long int. You also only need to add
'_8' (or 'L') to those values that would exceed huge(1) in
magnitude as integer*4 is a proper subset of integer*8 and
Fortran does conversion when required.
On 10/2/2024 11:27 PM, Steven G. Kargl wrote:
On Wed, 02 Oct 2024 14:30:48 -0500, Lynn McGuire wrote:
On 10/2/2024 2:00 AM, Lawrence D'Oliveiro wrote:
On Tue, 1 Oct 2024 21:58:40 -0500, Lynn McGuire wrote:
I need many of my integers to be integer*8 in my port to 64 bit. In >>>>> C/C++ code, I can say 123456L to mean a long long value, generally 64 >>>>> bit. Is there a corresponding way to do this in Fortran ...
integer(kind = 8), parameter :: bigval = 9223372036854775807_8
print *, bigval
prints
9223372036854775807
Thanks !
I was afraid of that. I will have to put _8 in about 100,000 lines of
my F77 code. And the future conversion to C++ will need special handling. >>>
If you 100,000 lines of C++ without a trailing 'L', you would
need to add 'L' to get a long int. You also only need to add
'_8' (or 'L') to those values that would exceed huge(1) in
magnitude as integer*4 is a proper subset of integer*8 and
Fortran does conversion when required.
If Fortran does an automatic conversion from I*4 to I*8, why does the compiler gripe at me that the integer constant does not match the
subroutine argument type ?
Lynn McGuire wrote:
I need many of my integers to be integer*8 in my port to 64 bit. In
C/C++ code, I can say 123456L to mean a long long value, generally 64
bit. Is there a corresponding way to do this in Fortran or am I stuck
with:
call xyz (1)
subroutine xyz (ivalue)
integer*8 ivalue
...
return end
must be:
integer*8 ivalue
...
ivalue = 1
call xyz (ivalue)
This is not actually a Fortran issue as such, it's all about a specific compiler (GNU Fortran).
On Thu, 03 Oct 2024 14:45:31 +0200, R Daneel Olivaw wrote:
Lynn McGuire wrote:
I need many of my integers to be integer*8 in my port to 64 bit. In
C/C++ code, I can say 123456L to mean a long long value, generally 64
bit. Is there a corresponding way to do this in Fortran or am I stuck
with:
call xyz (1)
subroutine xyz (ivalue)
integer*8 ivalue
...
return end
must be:
integer*8 ivalue
...
ivalue = 1
call xyz (ivalue)
This is not actually a Fortran issue as such, it's all about a specific
compiler (GNU Fortran).
If we overlook the nonstandard type in the declaration, and agree
that the compiler will accept 'integer*8', then the program is
still invalid Fortran. It's technically not a Fortran issue. It
is a programmer issue.
On Thu, 03 Oct 2024 02:06:28 -0500, Lynn McGuire wrote:
On 10/2/2024 11:27 PM, Steven G. Kargl wrote:
On Wed, 02 Oct 2024 14:30:48 -0500, Lynn McGuire wrote:
On 10/2/2024 2:00 AM, Lawrence D'Oliveiro wrote:
On Tue, 1 Oct 2024 21:58:40 -0500, Lynn McGuire wrote:
I need many of my integers to be integer*8 in my port to 64 bit. In >>>>>> C/C++ code, I can say 123456L to mean a long long value, generally 64 >>>>>> bit. Is there a corresponding way to do this in Fortran ...
integer(kind = 8), parameter :: bigval = 9223372036854775807_8 >>>>> print *, bigval
prints
9223372036854775807
Thanks !
I was afraid of that. I will have to put _8 in about 100,000 lines of >>>> my F77 code. And the future conversion to C++ will need special handling. >>>>
If you 100,000 lines of C++ without a trailing 'L', you would
need to add 'L' to get a long int. You also only need to add
'_8' (or 'L') to those values that would exceed huge(1) in
magnitude as integer*4 is a proper subset of integer*8 and
Fortran does conversion when required.
If Fortran does an automatic conversion from I*4 to I*8, why does the
compiler gripe at me that the integer constant does not match the
subroutine argument type ?
Well, to begin, you were talking about numeric literal constants.
I doubt you add '_8' (or 'L') to all entities declared as 'integer*4'
(or long int).
integer*8 i ! 42 is integer*4 and automatically converted to integer*8
i = 42 ! on assignment.
i = 3_8 * 2 ! Mixed-mode math. 2 is magically converted to integer*8
The compiler is not complaining. It is informing you of an mismatch
between an actual argument and the dummy argument. If one is 'integer*4'
and the other 'integer*8', you have 32 undefined bits.
As the person who gave gfortran the -fdefault-integer-8 option, I hope
your XXX kloc of code uses neither equivalence nor common blocks.
Steven G. Kargl wrote:
On Thu, 03 Oct 2024 14:45:31 +0200, R Daneel Olivaw wrote:
Lynn McGuire wrote:
I need many of my integers to be integer*8 in my port to 64 bit. In
C/C++ code, I can say 123456L to mean a long long value, generally 64
bit. Is there a corresponding way to do this in Fortran or am I stuck >>>> with:
call xyz (1)
subroutine xyz (ivalue)
integer*8 ivalue
...
return end
must be:
integer*8 ivalue
...
ivalue = 1
call xyz (ivalue)
This is not actually a Fortran issue as such, it's all about a specific
compiler (GNU Fortran).
If we overlook the nonstandard type in the declaration, and agree
that the compiler will accept 'integer*8', then the program is
still invalid Fortran. It's technically not a Fortran issue. It
is a programmer issue.
Take a pragmatic approach, if that's the way the compiler wants you to
do it then do it that way.
Years ago I was converting a suite of programs from one OS/hardware
platform to another. One program had serious problems because type
"real" had insufficient precision on the new machine, that machine
offered a compile option which meant "real" automatically meant "double precision" and - after checking for "equivalence" and common" statements
- that's the way I went. Problem solved. This was back in the days of Fortran IV but I don't think I've ever seen anyone assigning Hollerith values to Real numbers so that was not a problem either.
On 10/3/2024 10:02 AM, Steven G. Kargl wrote:
On Thu, 03 Oct 2024 02:06:28 -0500, Lynn McGuire wrote:
On 10/2/2024 11:27 PM, Steven G. Kargl wrote:As the person who gave gfortran the -fdefault-integer-8 option, I hope
your XXX kloc of code uses neither equivalence nor common blocks.
I have 197 common blocks included from dedicated files and a massive
number of equivalences all over the place. Several of the equivalences
are actually in the common block files. The equivalences have made the eventual C++ conversion of the Fortran code tricky.
This code is 850,000 lines of F77 code and 50,000 lines of C++ code that dates back to 1965 or so. Half of the code is Fortran IV and half is
F77. It has been ported to 12 ? different platforms, mostly mainframes
in the 1960s, 1970s, 1980s, and 1990s.
My personal recommendation would be to do a proper porting from
integer (aka integer*4) to integer(kind=8). And, yes, 8 in the
'kind=8' is not portable.
My code used to assign Hollerith to Real numbers but I ripped that out
years ago in a project to get rid of Hollerith.
On Thu, 3 Oct 2024 14:32:28 -0500, Lynn McGuire wrote:
I have 197 common blocks included from dedicated files and a massive
number of equivalences all over the place.
Try getting rid of at least some of them, by using “contains”.
On 10/3/2024 5:08 PM, Lawrence D'Oliveiro wrote:
On Thu, 3 Oct 2024 14:32:28 -0500, Lynn McGuire wrote:
I have 197 common blocks included from dedicated files and a massive
number of equivalences all over the place.
Try getting rid of at least some of them, by using “contains”.
What does "contains" do ? My knowledge of Fortran stopped at F77+.
On 03/10/2024 20:59, Steven G. Kargl wrote:different purposes: at least one uses kinds 1, 2, 3, 4 for the four most common numbers of bytes where other compilers use 1, 2, 4, 8. But if you
My personal recommendation would be to do a proper porting from
integer (aka integer*4) to integer(kind=8). And, yes, 8 in the
'kind=8' is not portable.
Yes because different compilers use different integer kind numbers for
On Thu, 3 Oct 2024 17:13:40 -0500, Lynn McGuire wrote:
On 10/3/2024 5:08 PM, Lawrence D'Oliveiro wrote:
On Thu, 3 Oct 2024 14:32:28 -0500, Lynn McGuire wrote:
I have 197 common blocks included from dedicated files and a massive
number of equivalences all over the place.
Try getting rid of at least some of them, by using “contains”.
What does "contains" do ? My knowledge of Fortran stopped at F77+.
Pick up a Fortran-90-or-later spec. This is not your father’s Fortran any more. “contains” lets you put subroutines and functions directly in the main program, so they can refer directly to program globals instead of
having to go through “common” blocks.
I posted an example of modernized Fortran code right here a few months
ago, and I see there’s a comment from you on it, so you must have seen it.
On Thu, 3 Oct 2024 17:13:40 -0500, Lynn McGuire wrote:
On 10/3/2024 5:08 PM, Lawrence D'Oliveiro wrote:
On Thu, 3 Oct 2024 14:32:28 -0500, Lynn McGuire wrote:
I have 197 common blocks included from dedicated files and a massive
number of equivalences all over the place.
Try getting rid of at least some of them, by using “contains”.
What does "contains" do ? My knowledge of Fortran stopped at F77+.
Pick up a Fortran-90-or-later spec. This is not your father’s Fortran any more. “contains” lets you put subroutines and functions directly in the main program, so they can refer directly to program globals instead of
having to go through “common” blocks.
I posted an example of modernized Fortran code right here a few months
ago, and I see there’s a comment from you on it, so you must have seen it.
I started writing Fortran IV in 1975. Been down a lot of roads since
then. I've written software in Fortran IV and 77, Pascal, C, C++, Curl,
etc. They are all running together now, I am getting old.
On Thu, 3 Oct 2024 14:34:01 -0500, Lynn McGuire wrote:
My code used to assign Hollerith to Real numbers but I ripped that out
years ago in a project to get rid of Hollerith.
Fortran was the first programming language I learned (from the Anna Burke Harris book). The only kind of string literals I can remember in that
first learning were Hollerith literals. I liked the fact that they were unambiguous: because length was explicit up front, you could any
characters you liked in them.
Later I discovered that “normal” people preferred explicitly-delimited string literals.
but not as friendly as
character*28 txthdr /'Text header, with a comma ' /
On Fri, 4 Oct 2024 12:13:52 +0200, R Daneel Olivaw wrote:
but not as friendly as
character*28 txthdr /'Text header, with a comma ' /
With all these additions to Fortran, I keep wondering “when will they finish reinventing PL/I?”. Because at an early point in the development
of PL/I, they were going to call it “FORTRAN VI”.
One PL/I feature still missing from Fortran is VARYING strings.
On Fri, 4 Oct 2024 12:13:52 +0200, R Daneel Olivaw wrote:
but not as friendly as
character*28 txthdr /'Text header, with a comma ' /
With all these additions to Fortran, I keep wondering “when will they finish reinventing PL/I?”. Because at an early point in the development of PL/I, they were going to call it “FORTRAN VI”.
One PL/I feature still missing from Fortran is VARYING strings.
I need many of my integers to be integer*8 in my port to 64 bit. In C/
C++ code, I can say 123456L to mean a long long value, generally 64
bit. Is there a corresponding way to do this in Fortran or am I stuck with:
call xyz (1)
subroutine xyz (ivalue)
integer*8 ivalue
...
return end
must be:
integer*8 ivalue
...
ivalue = 1
call xyz (ivalue)
Thanks,
Lynn
Yup, Perl, not Curl. AutoLisp.
Yes, I am porting from Open Watcom C++ and F77 to Simply Fortran C++ and GFortran right now. Lots of new stuff that I won't use. Incredibly
better error detection, especially on variable types and bounds.
On Fri, 04 Oct 2024 20:04:05 +0000, Lawrence D'Oliveiro wrote:
On Fri, 4 Oct 2024 12:13:52 +0200, R Daneel Olivaw wrote:
but not as friendly as
character*28 txthdr /'Text header, with a comma ' /
With all these additions to Fortran, I keep wondering “when will they
finish reinventing PL/I?”. Because at an early point in the development
of PL/I, they were going to call it “FORTRAN VI”.
One PL/I feature still missing from Fortran is VARYING strings.
The above line of code in not standard conforming Fortran.
Steven G. Kargl wrote:
On Fri, 04 Oct 2024 20:04:05 +0000, Lawrence D'Oliveiro wrote:
On Fri, 4 Oct 2024 12:13:52 +0200, R Daneel Olivaw wrote:
but not as friendly as
character*28 txthdr /'Text header, with a comma ' /
With all these additions to Fortran, I keep wondering “when will they
finish reinventing PL/I?”. Because at an early point in the development >>> of PL/I, they were going to call it “FORTRAN VI”.
One PL/I feature still missing from Fortran is VARYING strings.
The above line of code in not standard conforming Fortran.
I have not fed it through the compiler I used to use (mainframe, and I
no longer have access) but that compiler conformed to Fortran77 to the extent they did not even offer integer*8.
They did have some local extensions (statement functions) but they were clearly marked as non-standard in the manuals.
On 10/4/2024 3:04 PM, Lawrence D'Oliveiro wrote:
On Fri, 4 Oct 2024 12:13:52 +0200, R Daneel Olivaw wrote:
but not as friendly as
character*28 txthdr /'Text header, with a comma ' /
With all these additions to Fortran, I keep wondering “when will they
finish reinventing PL/I?”. Because at an early point in the development of >> PL/I, they were going to call it “FORTRAN VI”.
One PL/I feature still missing from Fortran is VARYING strings.
Fortran does have a form of varying string...just not super convenient to use in the general case.
On 04/10/2024 21:36, Gary Scott wrote:
On 10/4/2024 3:04 PM, Lawrence D'Oliveiro wrote:
On Fri, 4 Oct 2024 12:13:52 +0200, R Daneel Olivaw wrote:
but not as friendly as
character*28 txthdr /'Text header, with a comma ' /
With all these additions to Fortran, I keep wondering “when will they
finish reinventing PL/I?”. Because at an early point in the
development of
PL/I, they were going to call it “FORTRAN VI”.
One PL/I feature still missing from Fortran is VARYING strings.
Fortran does have a form of varying string...just not super convenient
to use in the general case.
Yes but for practical purposes it only works for scalars, not arrays.
Since nearly all the rest of Fortran is based on the (unstated, but widely-understood) principle that arrays are first-class objects, this
is a real pity.
On Fri, 4 Oct 2024 23:10:29 -0500, Lynn McGuire wrote:
Yup, Perl, not Curl. AutoLisp.
Poor you. The idiosyncratic syntax of Lisp without the redeeming advanced features.
Yes, I am porting from Open Watcom C++ and F77 to Simply Fortran C++ and
GFortran right now. Lots of new stuff that I won't use. Incredibly
better error detection, especially on variable types and bounds.
If I were you, I would look for opportunities to simplify things in that Fortran code by using new features, where I have to make major
modifications to those parts anyway.
I really liked the flexibility of string/text processing of IBM's DCF/Script/GML. How that was powerful string handling.
On Sat, 5 Oct 2024 13:52:01 -0500, Gary Scott wrote:
I really liked the flexibility of string/text processing of IBM's
DCF/Script/GML. How that was powerful string handling.
As good as Perl?
On 10/5/2024 6:07 PM, Lawrence D'Oliveiro wrote:
On Sat, 5 Oct 2024 13:52:01 -0500, Gary Scott wrote:
I really liked the flexibility of string/text processing of IBM's
DCF/Script/GML. How that was powerful string handling.
As good as Perl?
vastly better, but it was specifically a text (document) processor,
vastly different purpose.
On Sat, 5 Oct 2024 19:39:31 -0500, Gary Scott wrote:Extremely powerful substitution, full control of fonts, code points,
On 10/5/2024 6:07 PM, Lawrence D'Oliveiro wrote:
On Sat, 5 Oct 2024 13:52:01 -0500, Gary Scott wrote:
I really liked the flexibility of string/text processing of IBM's
DCF/Script/GML. How that was powerful string handling.
As good as Perl?
vastly better, but it was specifically a text (document) processor,
vastly different purpose.
How could it have been better without regular expressions?
On 10/5/2024 8:58 PM, Lawrence D'Oliveiro wrote:
How could it have been better without regular expressions?
Extremely powerful substitution ...
full control of fonts, code points, code pages, dynamically controlled overprinting, image handling ...
direct/binary datastream writing/editing, formatting page columns,
gutters, running headings/footings, tables, lists (order, unordered,
etc.) ...
... full support for foreign languages, double byte character sets
decades before unicode ...
Directly define your own gml (predecessor to html) tags.
On Sat, 5 Oct 2024 21:35:42 -0500, Gary Scott wrote:
On 10/5/2024 8:58 PM, Lawrence D'Oliveiro wrote:
How could it have been better without regular expressions?
Extremely powerful substitution ...
But without regular expressions, that kind of thing gets quite limited.
full control of fonts, code points, code pages, dynamically controlled
overprinting, image handling ...
troff was doing this sort of thing years before. Remember that the Unix
folks at Bell Labs got the funding to develop their new OS primarily on
the rationale that it would offer good text-processing facilities, like
you describe.
direct/binary datastream writing/editing, formatting page columns,
gutters, running headings/footings, tables, lists (order, unordered,
etc.) ...
I notice no mention of line-numbering. That’s rather crucial for legal documents -- another selling point that the Bell Labs folks were able to address.
... full support for foreign languages, double byte character sets
decades before unicode ...
I don’t know why you think that was such a radical feature, given that the Koreans introduced their national double-byte code in 1974, the Japanese theirs in 1978, and the Chinese did GB2312 in 1980.
Directly define your own gml (predecessor to html) tags.
troff incorporated the idea of macros right from the beginning.
On 10/5/2024 10:39 PM, Lawrence D'Oliveiro wrote:And yes it supported line numbers and change markups.
On Sat, 5 Oct 2024 21:35:42 -0500, Gary Scott wrote:
On 10/5/2024 8:58 PM, Lawrence D'Oliveiro wrote:
How could it have been better without regular expressions?
Extremely powerful substitution ...
But without regular expressions, that kind of thing gets quite limited.
full control of fonts, code points, code pages, dynamically controlled
overprinting, image handling ...
troff was doing this sort of thing years before. Remember that the Unix
folks at Bell Labs got the funding to develop their new OS primarily on
the rationale that it would offer good text-processing facilities, like
you describe.
direct/binary datastream writing/editing, formatting page columns,
gutters, running headings/footings, tables, lists (order, unordered,
etc.) ...
I notice no mention of line-numbering. That’s rather crucial for legal
documents -- another selling point that the Bell Labs folks were able to
address.
... full support for foreign languages, double byte character sets
decades before unicode ...
I don’t know why you think that was such a radical feature, given that
the
Koreans introduced their national double-byte code in 1974, the Japanese
theirs in 1978, and the Chinese did GB2312 in 1980.
Directly define your own gml (predecessor to html) tags.
troff incorporated the idea of macros right from the beginning.
This stuff was done in the 60s and 70s, certainly it evolved over time.
I have 197 common blocks included from dedicated files and a massive
number of equivalences all over the place. Several of the equivalences
are actually in the common block files. The equivalences have made the eventual C++ conversion of the Fortran code tricky.
Lynn McGuire <lynnmcguire5@gmail.com> schrieb:
I have 197 common blocks included from dedicated files and a massive
number of equivalences all over the place. Several of the equivalences
are actually in the common block files. The equivalences have made the
eventual C++ conversion of the Fortran code tricky.
What do you use the equivalences for? Saving memory? Then this
should not be a large issue on modern machines.
If you are using them for tricks with type conversion, then you
are on thin ice already, and have been since Fortran 66.
And if you have a few big arrays, then changing those to ALLOCATABLE
and allocating them at runtime might well be straightforward.
Equivalences are an effective way of building data structures, you can
do that with Common as well but sometimes equivalence is more suitable.
Lynn McGuire <lynnmcguire5@gmail.com> schrieb:
I have 197 common blocks included from dedicated files and a massive
number of equivalences all over the place. Several of the equivalences
are actually in the common block files. The equivalences have made the
eventual C++ conversion of the Fortran code tricky.
What do you use the equivalences for? Saving memory? Then this
should not be a large issue on modern machines.
If you are using them for tricks with type conversion, then you
are on thin ice already, and have been since Fortran 66.
And if you have a few big arrays, then changing those to ALLOCATABLE
and allocating them at runtime might well be straightforward.
R Daneel Olivaw <Danny@hyperspace.vogon.gov> schrieb:
Equivalences are an effective way of building data structures, you can
do that with Common as well but sometimes equivalence is more suitable.
Can you give an example? I have a hard time imagining what it would
be useful for.
On 10/13/2024 7:18 AM, Thomas Koenig wrote:
What do you use the equivalences for?
About the only thing I've used it for is for performing mathematical operations on things like characters for encryption or compression algorithms. Using a function for that doesn't appeal to me.
integer record (100), reckey, reccod
c or integer*4
character*40 recnam, recstr, rectwn
c
equivalence (record, reckey), (record (2), recnam)
equivalence (record (12), recstr), (record (22), rectwn)
equivalence (record (32), reccod)
c and so on
Lynn McGuire <lynnmcguire5@gmail.com> schrieb:
I have 197 common blocks included from dedicated files and a massive
number of equivalences all over the place. Several of the equivalences
are actually in the common block files. The equivalences have made the
eventual C++ conversion of the Fortran code tricky.
What do you use the equivalences for? Saving memory? Then this
should not be a large issue on modern machines.
If you are using them for tricks with type conversion, then you
are on thin ice already, and have been since Fortran 66.
And if you have a few big arrays, then changing those to ALLOCATABLE
and allocating them at runtime might well be straightforward.
Lynn McGuire <lynnmcguire5@gmail.com> schrieb:
I have 197 common blocks included from dedicated files and a massive
number of equivalences all over the place. Several of the equivalences
are actually in the common block files. The equivalences have made the
eventual C++ conversion of the Fortran code tricky.
What do you use the equivalences for? Saving memory? Then this
should not be a large issue on modern machines.
If you are using them for tricks with type conversion, then you
are on thin ice already, and have been since Fortran 66.
And if you have a few big arrays, then changing those to ALLOCATABLE
and allocating them at runtime might well be straightforward.
"DYNOSOR: a set of subroutines for dynamic memory organization in
Fortran programs"
https://dl.acm.org/doi/10.1145/954654.954661
One of our guys went to an ACM conference in 1977 and came back with
this paper. It was the answer to our memory problems on the Univac
1108, the CDC 7600, and later the IBM 370.
I converted the memory allocation scheme from a common block in 1992 ???
to using the C malloc, realloc, and free library functions. Worked like
a champ on Unix, Vax VMS, IBM mainframes, and PC DOS using various F77 compilers.
Lynn McGuire <lynnmcguire5@gmail.com> schrieb:
"DYNOSOR: a set of subroutines for dynamic memory organization in
Fortran programs"
https://dl.acm.org/doi/10.1145/954654.954661
One of our guys went to an ACM conference in 1977 and came back with
this paper. It was the answer to our memory problems on the Univac
1108, the CDC 7600, and later the IBM 370.
Only the first page is readable, the rest is behind paywall,
unfortunately.
I converted the memory allocation scheme from a common block in 1992 ???
to using the C malloc, realloc, and free library functions. Worked like
a champ on Unix, Vax VMS, IBM mainframes, and PC DOS using various F77
compilers.
If you're already using dynamic allocation, then you can of course
keep on doing what you are doing. It will not be officially
supported, but the likelyhood of this continuing to work is high
(no guarantees, though).
Lynn McGuire<lynnmcguire5@gmail.com> schrieb:
"DYNOSOR: a set of subroutines for dynamic memory organization inOnly the first page is readable, the rest is behind paywall,
Fortran programs"
https://dl.acm.org/doi/10.1145/954654.954661
One of our guys went to an ACM conference in 1977 and came back with
this paper. It was the answer to our memory problems on the Univac
1108, the CDC 7600, and later the IBM 370.
unfortunately.
Lynn McGuire <lynnmcguire5@gmail.com> schrieb:
"DYNOSOR: a set of subroutines for dynamic memory organization in
Fortran programs"
https://dl.acm.org/doi/10.1145/954654.954661
One of our guys went to an ACM conference in 1977 and came back with
this paper. It was the answer to our memory problems on the Univac
1108, the CDC 7600, and later the IBM 370.
Only the first page is readable, the rest is behind paywall,
unfortunately.
I converted the memory allocation scheme from a common block in 1992 ???
to using the C malloc, realloc, and free library functions. Worked like
a champ on Unix, Vax VMS, IBM mainframes, and PC DOS using various F77
compilers.
If you're already using dynamic allocation, then you can of course
keep on doing what you are doing. It will not be officially
supported, but the likelyhood of this continuing to work is high
(no guarantees, though).
I never would
have guessed that 47 years later, FORTRAN would be Fortran and ALGOL
would be mostly forgotten.)
I am thinking that 32 bit and 64 bit are here to stay for quite a while.
On Tue, 15 Oct 2024 02:43:47 -0600, Louis Krupp wrote:
I never wouldWhat irks me most is the prevalence of “=” over “:=” for assignment.
have guessed that 47 years later, FORTRAN would be Fortran and ALGOL
would be mostly forgotten.)
But, looking at language specs for Fortran-90 and later, would you still
say “FORTRAN is Fortran”?
FORTRAN was my first (computer) language.
the B5500 was replaced by a B6700, which used EBCDIC, ALGOL used ":=" instead of the arrow, which I missed.
On Tue, 15 Oct 2024 17:03:01 -0500, Lynn McGuire wrote:
I am thinking that 32 bit and 64 bit are here to stay for quite a while.
I think typical memory sizes are doubling maybe every couple of years, if
not sooner. Currently maybe 48-bit memory addresses are sufficient, but it will be just a matter of a few decades before even 64-bit addresses won’t be enough.
The guys at NIST are talking about quadruple precision as a standard.
type :: record_type
integer(kind = intsize) reckey
character(len = strmax) :: recnam, recstr, recwn
integer(kind = intsize) reccod
! and so on
end type record_type
On 10/5/2024 1:39 AM, Lawrence D'Oliveiro wrote:
If I were you, I would look for opportunities to simplify things in
that Fortran code by using new features, where I have to make major
modifications to those parts anyway.
All of the modifications that I am making are minor. Mostly changing my
old 8 byte data structure/union to I*8 and L*8.
I include all of my common blocks as files to stop typos.
Lynn McGuire <lynnmcguire5@gmail.com> schrieb:
I include all of my common blocks as files to stop typos.
That is surely an old technique, but only really works to 100%
if you adhere to some additional style constraints in your code.
Consider
foo.f:
DIMENSION A(10)
INCLUDE "common.inc"
bar.f:
INCLUDE "common.inc"
(without the DIMENSION)
common.inc:
COMMON /COMMON/ A
Here is one of my 197 common block include files, global.inc:
C global.inc
C
C
C 11/21/19 Lynn McGuire pmr 6299, add new ncp max used variable for chemtran
...
integer MAX_NCP
PARAMETER (MAX_NCP = 1000)
COMMON / GLOBAL / KTRACE, NCP, SETSTP, NDYNER, NERQQQ, LNOLIMIT,
* do_not_call_pivf, do_not_call_adbf,
* ne_did_not_converge, equipment_fail_count,
* lrespect_user_pitch, do_not_call_threephs,
* do_not_call_flai, do_not_call_liqh,
* do_not_call_vaph, thermo_init_failed,
* num_crude_streams, print_streams_for_each_unit,
* do_not_call_solid_isothermal_flash,
* ncp_max_used
integer KTRACE
integer NCP
logical SETSTP
integer NDYNER
integer NERQQQ
integer num_crude_streams
logical LNOLIMIT
logical do_not_call_pivf
logical do_not_call_adbf
logical lrespect_user_pitch
logical do_not_call_threephs
logical do_not_call_flai
logical do_not_call_liqh
logical do_not_call_vaph
logical thermo_init_failed
logical print_streams_for_each_unit
logical do_not_call_solid_isothermal_flash
C this is to record the ncp max used for chemtran since itchanges ncp on the fly
integer ncp_max_used
On Tue, 22 Oct 2024 00:07:41 -0500, Lynn McGuire wrote:
Here is one of my 197 common block include files, global.inc:
C global.inc
C
C
C 11/21/19 Lynn McGuire pmr 6299, add new ncp max used variable for chemtran
Those are the sorts of things that belong in your version control
system.
...
What, no “implicit none”? Or do you put this in the including files?
integer MAX_NCP
PARAMETER (MAX_NCP = 1000)
All these pairs of lines can be replaced with single lines, e.g.
integer, parameter :: MAX_NCP = 1000
COMMON / GLOBAL / KTRACE, NCP, SETSTP, NDYNER, NERQQQ, LNOLIMIT,
* do_not_call_pivf, do_not_call_adbf,
* ne_did_not_converge, equipment_fail_count,
* lrespect_user_pitch, do_not_call_threephs,
* do_not_call_flai, do_not_call_liqh,
* do_not_call_vaph, thermo_init_failed,
* num_crude_streams, print_streams_for_each_unit,
* do_not_call_solid_isothermal_flash,
* ncp_max_used
integer KTRACE
integer NCP
logical SETSTP
integer NDYNER
integer NERQQQ
integer num_crude_streams
logical LNOLIMIT
logical do_not_call_pivf
logical do_not_call_adbf
logical lrespect_user_pitch
logical do_not_call_threephs
logical do_not_call_flai
logical do_not_call_liqh
logical do_not_call_vaph
logical thermo_init_failed
logical print_streams_for_each_unit
logical do_not_call_solid_isothermal_flash
C this is to record the ncp max used for chemtran since itchanges ncp on the fly
integer ncp_max_used
Much more concisely:
module GLOBAL
integer :: KTRACE, NCP, SETSTP, NDYNER, NERQQQ, num_crude_streams
logical :: LNOLIMIT, do_not_call_pivf, do_not_call_adbf, lrespect_user_pitch, &
do_not_call_threephs, do_not_call_flai, do_not_call_liqh, do_not_call_vaph, &
thermo_init_failed, print_streams_for_each_unit, do_not_call_solid_isothermal_flash
integer :: ncp_max_used
! this is to record the ncp max used for chemtran since itchanges ncp on the fly
end module GLOBAL
Then you just do “use GLOBAL” where you need these definitions.
etc etc
On Tue, 22 Oct 2024 00:07:41 -0500, Lynn McGuire wrote:
Here is one of my 197 common block include files, global.inc:
C global.inc
C
C
C 11/21/19 Lynn McGuire pmr 6299, add new ncp max used variable for chemtran
Those are the sorts of things that belong in your version control
system.
...
What, no “implicit none”? Or do you put this in the including files?
integer MAX_NCP
PARAMETER (MAX_NCP = 1000)
All these pairs of lines can be replaced with single lines, e.g.
integer, parameter :: MAX_NCP = 1000
COMMON / GLOBAL / KTRACE, NCP, SETSTP, NDYNER, NERQQQ, LNOLIMIT,
* do_not_call_pivf, do_not_call_adbf,
* ne_did_not_converge, equipment_fail_count,
* lrespect_user_pitch, do_not_call_threephs,
* do_not_call_flai, do_not_call_liqh,
* do_not_call_vaph, thermo_init_failed,
* num_crude_streams, print_streams_for_each_unit,
* do_not_call_solid_isothermal_flash,
* ncp_max_used
integer KTRACE
integer NCP
logical SETSTP
integer NDYNER
integer NERQQQ
integer num_crude_streams
logical LNOLIMIT
logical do_not_call_pivf
logical do_not_call_adbf
logical lrespect_user_pitch
logical do_not_call_threephs
logical do_not_call_flai
logical do_not_call_liqh
logical do_not_call_vaph
logical thermo_init_failed
logical print_streams_for_each_unit
logical do_not_call_solid_isothermal_flash
C this is to record the ncp max used for chemtran since itchanges ncp on the fly
integer ncp_max_used
Much more concisely:
module GLOBAL
integer :: KTRACE, NCP, SETSTP, NDYNER, NERQQQ, num_crude_streams
logical :: LNOLIMIT, do_not_call_pivf, do_not_call_adbf, lrespect_user_pitch, &
do_not_call_threephs, do_not_call_flai, do_not_call_liqh, do_not_call_vaph, &
thermo_init_failed, print_streams_for_each_unit, do_not_call_solid_isothermal_flash
integer :: ncp_max_used
! this is to record the ncp max used for chemtran since itchanges ncp on the fly
end module GLOBAL
Then you just do “use GLOBAL” where you need these definitions.
etc etc
BTW, my software dates before version control systems.
And I like change notes in my code, it helps to figure out what
is going on.
And some day we are going to change version control systems again.
And I am not going to upgrade 850,000 lines of Fortran F77 code to F90
code just to have prettier code. I would still be here in 10 years
fixing all of the bugs from that disaster.
On Wed, 23 Oct 2024 13:56:47 -0500, Lynn McGuire wrote:
BTW, my software dates before version control systems.
Quite a bit of mine did, too, back in the day. Didn’t stop me from putting them into version control. I even wrote some utility scripts to help with
the process <https://bitbucket.org/ldo17/fake_vcs/>.
And I like change notes in my code, it helps to figure out what
is going on.
You soon discover that version control history logs do all that, and more. Remember, they show you, not just the comments you entered, but the actual file diffs that go with them. Your current header comments cannot provide that information.
Git also offers something you’re currently probably not doing because it’s
too difficult to do: branching and merging.
And some day we are going to change version control systems again.
That will likely not be the difficult part. All the open-source VCSes
offer bulk import/export functions, to allow moving entire repos and
commit histories between them. Git offered plugins to allow easier interoperation with other VCSes like Mercurial and SVN; any future replacement for Git will have to do at least as well.
And I am not going to upgrade 850,000 lines of Fortran F77 code to F90
code just to have prettier code. I would still be here in 10 years
fixing all of the bugs from that disaster.
Think about making it easier to maintain going forward.
I am going to change all the F77 code to C++ some day.
I am going to change all the F77 code to C++ some day. I already have a heavily modified version of F2C that I have rewritten extensively and already moved several hundred subroutines from F77 to C++.
The biggest
problem is the F77 write statements.
F2C fixes the other big problem
automatically, the change of initial array index from one to zero.
Lynn McGuire <lynnmcguire5@gmail.com> schrieb:
I am going to change all the F77 code to C++ some day. I already have a
heavily modified version of F2C that I have rewritten extensively and
already moved several hundred subroutines from F77 to C++.
Modern Fortran might be the easier way, because a change can be done incrementally, and this...
The biggest
problem is the F77 write statements.
... would not be an issue. What features is modern Fortran missing that
you need C++ for?
F2C fixes the other big problem
automatically, the change of initial array index from one to zero.
If I remember correctly, it does so by issueing invalid C (or
C++), by using negative offsets from pointers. Might work now,
might not work tomorrow.
But note the IIRC above.
{
if (t <= component_data1.triplepointtemperature[k - 1]) {
solid_vapor_pressure (k, t, ps);
*star = ' ';
goto L99999;
}
L99999:
if (*ps < 1e-20) {
*ps = 1e-20;
}
if (*ps > 1e6) {
*ps = 1e6;
}
return 0;
} /* vapres */
On Fri, 25 Oct 2024 20:26:37 -0500, Lynn McGuire wrote:
{
if (t <= component_data1.triplepointtemperature[k - 1]) {
solid_vapor_pressure (k, t, ps);
*star = ' ';
goto L99999;
}
L99999:
if (*ps < 1e-20) {
*ps = 1e-20;
}
if (*ps > 1e6) {
*ps = 1e6;
}
return 0;
} /* vapres */
{
if (t <= component_data1.triplepointtemperature[k - 1])
{
solid_vapor_pressure(k, t, ps);
*star = ' ';
} /*if*/
*ps = fmin(fmax(*ps, 1e-20), 1e6);
return 0;
} /* vapres */
On 10/24/2024 1:28 AM, Thomas Koenig wrote:
Lynn McGuire <lynnmcguire5@gmail.com> schrieb:
F2C fixes the other big problem
automatically, the change of initial array index from one to zero.
If I remember correctly, it does so by issueing invalid C (or
C++), by using negative offsets from pointers. Might work now,
might not work tomorrow.
But note the IIRC above.
I want to move to a monolanguage environment. 50,000 lines of my calculation engine are C++ already. 850,000 lines to go.
The "parameter adjustment" above is explicitly listed as undefined
behavior, in annex J2 of n2596.pdf (for example):
"Addition or subtraction of a pointer into, or just beyond, an array
object and an integer type produces a result that does not point into,
or just beyond, the same array object (6.5.6)."
Lynn McGuire <lynnmcguire5@gmail.com> schrieb:
On 10/24/2024 1:28 AM, Thomas Koenig wrote:
Lynn McGuire <lynnmcguire5@gmail.com> schrieb:
F2C fixes the other big problem
automatically, the change of initial array index from one to zero.
If I remember correctly, it does so by issueing invalid C (or
C++), by using negative offsets from pointers. Might work now,
might not work tomorrow.
But note the IIRC above.
I want to move to a monolanguage environment. 50,000 lines of my
calculation engine are C++ already. 850,000 lines to go.
That motivation, I understand, especially if the GUI code is in C++,
but there is a caveat. Consider
subroutine foo(i,n)
integer array(10)
common array
integer n
integer i(n)
integer k
do k=1,n
i(k) = k + array(k)
end do
end
which gets translated by stock f2c (to which you may have made
adjustments) into
#include "f2c.h"
/* Common Block Declarations */
struct {
integer array[10];
} _BLNK__;
#define _BLNK__1 _BLNK__
/* Subroutine */ int foo_(integer *i__, integer *n)
{
/* System generated locals */
integer i__1;
/* Local variables */
static integer k;
/* Parameter adjustments */
--i__;
/* Function Body */
i__1 = *n;
for (k = 1; k <= i__1; ++k) {
i__[k] = k + _BLNK__1.array[k - 1];
}
return 0;
} /* foo_ */
The common block handling looks OK, but the dummy argument
(aka parameters, in C parlance) handling is very probably not.
The "parameter adjustment" above is explicitly listed as undefined
behavior, in annex J2 of n2596.pdf (for example):
"Addition or subtraction of a pointer into, or just beyond, an
array object and an integer type produces a result that does not
point into, or just beyond, the same array object (6.5.6)."
Undefined behavior is the worst kind of error in your program
that you can have in C, it is not required to be diagnosed, and
compilers can, and do, make optimizations based on the assumption
that it does not happen, so this is liable to break in unforseen circumstances.
So if your version of f2c does the same, I would check the C++
standard if if has a similar provision (I strongly suspect so,
but I don't know), and, if that is the case, modify your version
of f2c to generate conforming code for array dummy arguments.
Otherwise, you are betting your company.
First, I include all of my 300+ common blocks as 200 files. I converted those separately and cleaned them up so that the static variables and defines are easy to peruse and understand. I delete all of the local
common block conversions by f2c in the subroutines and change them back
to include files. An easy cleanup that I have to do 5,000 times (4,000
to go now plus the 100+ subroutines that we have modified for customers since I started the conversion project two years ago).
I also removed the parameter adjustments from my copy of f2c. It is a little tricky but as you say, they are not legal code in C++.
On Sat, 26 Oct 2024 11:51:42 -0000 (UTC), Thomas Koenig wrote:
The "parameter adjustment" above is explicitly listed as undefined
behavior, in annex J2 of n2596.pdf (for example):
"Addition or subtraction of a pointer into, or just beyond, an array
object and an integer type produces a result that does not point into,
or just beyond, the same array object (6.5.6)."
Read it again: note the qualification “that does not point into, or just beyond, the same array object”. So long as it *does* point “into, or just
beyond, the same array object”, it is fine.
Lawrence D'Oliveiro <ldo@nz.invalid> schrieb:
On Sat, 26 Oct 2024 11:51:42 -0000 (UTC), Thomas Koenig wrote:
The "parameter adjustment" above is explicitly listed as undefined
behavior, in annex J2 of n2596.pdf (for example):
"Addition or subtraction of a pointer into, or just beyond, an array
object and an integer type produces a result that does not point into,
or just beyond, the same array object (6.5.6)."
Read it again: note the qualification “that does not point into, or
just beyond, the same array object”. So long as it *does* point “into, >> or just beyond, the same array object”, it is fine.
What you are writing is equivalent to
On Sat, 26 Oct 2024 21:38:38 -0000 (UTC), Thomas Koenig wrote:
Lawrence D'Oliveiro <ldo@nz.invalid> schrieb:
On Sat, 26 Oct 2024 11:51:42 -0000 (UTC), Thomas Koenig wrote:
The "parameter adjustment" above is explicitly listed as undefined
behavior, in annex J2 of n2596.pdf (for example):
"Addition or subtraction of a pointer into, or just beyond, an array
object and an integer type produces a result that does not point into, >>>> or just beyond, the same array object (6.5.6)."
Read it again: note the qualification “that does not point into, or
just beyond, the same array object”. So long as it *does* point “into, >>> or just beyond, the same array object”, it is fine.
What you are writing is equivalent to
You don’t understand what pointer arithmetic means, do you?
I've killfiled you in comp.arch, and I think it is a good time now
for comp.lang.fortran.
Lawrence D'Oliveiro <ldo@nz.invalid> schrieb:
On Sat, 26 Oct 2024 21:38:38 -0000 (UTC), Thomas Koenig wrote:
Lawrence D'Oliveiro <ldo@nz.invalid> schrieb:
On Sat, 26 Oct 2024 11:51:42 -0000 (UTC), Thomas Koenig wrote:
The "parameter adjustment" above is explicitly listed as undefined
behavior, in annex J2 of n2596.pdf (for example):
"Addition or subtraction of a pointer into, or just beyond, an array >>>>> object and an integer type produces a result that does not point
into, or just beyond, the same array object (6.5.6)."
Read it again: note the qualification “that does not point into, or
just beyond, the same array object”. So long as it *does* point
“into, or just beyond, the same array object”, it is fine.
What you are writing is equivalent to
You don’t understand what pointer arithmetic means, do you?
Lawrence D'Oliveiro <ldo@nz.invalid> schrieb:
On Sat, 26 Oct 2024 21:38:38 -0000 (UTC), Thomas Koenig wrote:
Lawrence D'Oliveiro <ldo@nz.invalid> schrieb:
On Sat, 26 Oct 2024 11:51:42 -0000 (UTC), Thomas Koenig wrote:
The "parameter adjustment" above is explicitly listed as undefined
behavior, in annex J2 of n2596.pdf (for example):
"Addition or subtraction of a pointer into, or just beyond, an array >>>>> object and an integer type produces a result that does not point into, >>>>> or just beyond, the same array object (6.5.6)."
Read it again: note the qualification “that does not point into, or
just beyond, the same array object”. So long as it *does* point “into, >>>> or just beyond, the same array object”, it is fine.
What you are writing is equivalent to
You don’t understand what pointer arithmetic means, do you?
I've killfiled you in comp.arch, and I think it is a good time now
for comp.lang.fortran.
Lynn McGuire <lynnmcguire5@gmail.com> schrieb:
First, I include all of my 300+ common blocks as 200 files. I converted
those separately and cleaned them up so that the static variables and
defines are easy to peruse and understand. I delete all of the local
common block conversions by f2c in the subroutines and change them back
to include files. An easy cleanup that I have to do 5,000 times (4,000
to go now plus the 100+ subroutines that we have modified for customers
since I started the conversion project two years ago).
Sounds like a lot of work...
I also removed the parameter adjustments from my copy of f2c. It is a
little tricky but as you say, they are not legal code in C++.
Very good, I think you're set then.
On Sun, 27 Oct 2024 08:05:47 -0000 (UTC), Thomas Koenig wrote:
Lawrence D'Oliveiro <ldo@nz.invalid> schrieb:
On Sat, 26 Oct 2024 21:38:38 -0000 (UTC), Thomas Koenig wrote:
Lawrence D'Oliveiro <ldo@nz.invalid> schrieb:
On Sat, 26 Oct 2024 11:51:42 -0000 (UTC), Thomas Koenig wrote:
The "parameter adjustment" above is explicitly listed as undefined >>>>>> behavior, in annex J2 of n2596.pdf (for example):
"Addition or subtraction of a pointer into, or just beyond, an array >>>>>> object and an integer type produces a result that does not point
into, or just beyond, the same array object (6.5.6)."
Read it again: note the qualification “that does not point into, or >>>>> just beyond, the same array object”. So long as it *does* point
“into, or just beyond, the same array object”, it is fine.
What you are writing is equivalent to
You don’t understand what pointer arithmetic means, do you?
Hey, look! Somebody who doesn’t understand how pointer arithmetic works!
On Sun, 27 Oct 2024 08:05:47 -0000 (UTC), Thomas Koenig wrote:
Lawrence D'Oliveiro <ldo@nz.invalid> schrieb:
On Sat, 26 Oct 2024 21:38:38 -0000 (UTC), Thomas Koenig wrote:
Lawrence D'Oliveiro <ldo@nz.invalid> schrieb:
On Sat, 26 Oct 2024 11:51:42 -0000 (UTC), Thomas Koenig wrote:
#include "f2c.h"
/* Common Block Declarations */
struct {
integer array[10];
} _BLNK__;
#define _BLNK__1 _BLNK__
/* Subroutine */ int foo_(integer *i__, integer *n)
{
/* System generated locals */
integer i__1;
/* Local variables */
static integer k;
/* Parameter adjustments */
--i__;
/* Function Body */
i__1 = *n;
for (k = 1; k <= i__1; ++k) {
i__[k] = k + _BLNK__1.array[k - 1];
}
return 0;
} /* foo_ */
The common block handling looks OK, but the dummy argument
(aka parameters, in C parlance) handling is very probably not.
[snipped ensuing conversation, which contained nothing of value.]The "parameter adjustment" above is explicitly listed as undefined >>>>>> behavior, in annex J2 of n2596.pdf (for example):
"Addition or subtraction of a pointer into, or just beyond, an array >>>>>> object and an integer type produces a result that does not point
into, or just beyond, the same array object (6.5.6)."
Sysop: | DaiTengu |
---|---|
Location: | Appleton, WI |
Users: | 991 |
Nodes: | 10 (0 / 10) |
Uptime: | 119:35:51 |
Calls: | 12,958 |
Files: | 186,574 |
Messages: | 3,265,636 |