Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Attempting to Compile and Execute Old Fortran 77 Code Using GFortran

786 views
Skip to first unread message

mm2...@scarletmail.rutgers.edu

unread,
Apr 29, 2020, 7:07:57 PM4/29/20
to
The code that I am working with was originally written in FORTRAN 77. I am hesitant to update all of the files to a more modern standard since there are multiple files thousands of lines long that rely on obsolete functions.

During compilation, I get a few type mismatch arguments, most of which are taken care of with -freal-4-real-8, but I am unsure if that is a permanent solution.

I currently use the following flags to compile all of the object files which are then compiled into the final executable: -ff2c -std=legacy -freal-4-real-8

The file in which the error occurs is compiled without the -freal flag because it uses a function that requires a real(4) variable.

The current error I am getting upon running the executable is: At line 2680 of file twopt.f Fortran runtime error: Assigned label is not a target label

The subroutine in which the error occurs takes in REENT as a logical parameter. ROUTE is later declared as an integer but is not assigned any value which I think might be the reason behind the problem. I used print statements to check its value before the error occurs, and REENT is true, and ROUTE is 0.

Code at lines 2678-2681:

IF (REENT) THEN REENT = .FALSE. GO TO ROUTE END IF

In the subroutine there is no statement label with the value of 0 which also might contribute to the error. Again, I am hesitant to edit the code too much since it supposedly worked as intended back in the ‘90s. Any help would be greatly appreciated.

FortranFan

unread,
Apr 29, 2020, 8:39:58 PM4/29/20
to
On Wednesday, April 29, 2020 at 7:07:57 PM UTC-4, mm2...@scarletmail.rutgers.edu wrote:

> The code that I am working with was originally written in FORTRAN 77. I am hesitant to update all of the files to a more modern standard since there are multiple files thousands of lines long that rely on obsolete functions.
>
> ..
>
> The current error I am getting upon running the executable is: At line 2680 of file twopt.f Fortran runtime error: Assigned label is not a target label
>
> The subroutine in which the error occurs takes in REENT as a logical parameter. ROUTE is later declared as an integer but is not assigned any value which I think might be the reason behind the problem. I used print statements to check its value before the error occurs, and REENT is true, and ROUTE is 0.
>
> Code at lines 2678-2681:
>
> IF (REENT) THEN REENT = .FALSE. GO TO ROUTE END IF
>
> In the subroutine there is no statement label with the value of 0 which also might contribute to the error. Again, I am hesitant to edit the code too much since it supposedly worked as intended back in the ‘90s. Any help would be greatly appreciated.


Look for statements that look like "ASSIGN NN TO ROUTE" in your offending subroutine. That's what is important. From what I understand, the value of 'ROUTE' itself is meaningless once it has defined in an ASSIGN statement.

Here's a simple test case involving typical 'spaghetti' structure with GO TO that I once had to contend with when I was rewriting some engineering code in use in industry to 'modern' Fortran: perhaps it might help you get some pointers on the issue you face. If nothing else, it will show this feature of assigned GO TO which has been deleted in the Fortran language is still supported by gfortran (and also Intel Fortran):

module m
contains
subroutine sub( a )
real, intent(in) :: a
integer :: route
logical :: lprint
lprint = .false.
10 continue
if ( lprint ) then
print *, "a is less than 0.5"
go to 999
end if
20 continue
if ( lprint ) then
print *, "a is greater than 0.5"
go to 999
end if
if ( a < 0.5 ) then
assign 10 to route
else
assign 20 to route
end if
lprint = .true.
print *, "route = ", route
go to route
999 continue
return
end subroutine
end module
use m, only : sub
real :: r
integer :: i
call random_seed()
do i = 1, 5
call random_number( r )
call sub( r )
end do
end

gfortran response below:
--- begin console output ---

C:\Temp>type p.f90
module m
contains
subroutine sub( a )
real, intent(in) :: a
integer :: route
logical :: lprint
lprint = .false.
10 continue
if ( lprint ) then
print *, "a is less than 0.5"
go to 999
end if
20 continue
if ( lprint ) then
print *, "a is greater than 0.5"
go to 999
end if
if ( a < 0.5 ) then
assign 10 to route
else
assign 20 to route
end if
lprint = .true.
print *, "route = ", route
go to route
999 continue
return
end subroutine
end module
use m, only : sub
real :: r
integer :: i
call random_seed()
do i = 1, 5
call random_number( r )
call sub( r )
end do
end

C:\Temp>gfortran -std=legacy p.f90 -o p.exe

C:\Temp>p.exe
route = 0
a is greater than 0.5
route = 0
a is less than 0.5
route = 0
a is greater than 0.5
route = 0
a is less than 0.5
route = 0
a is less than 0.5

C:\Temp>
--- end console output ---

Alternately if you can host your code some place online (GitHub?), you can have some readers review the code and advise you on how to work it without editing it much.

robin....@gmail.com

unread,
Apr 29, 2020, 11:09:58 PM4/29/20
to
On Thursday, April 30, 2020 at 9:07:57 AM UTC+10, mm2...@scarletmail.rutgers.edu wrote:
> The code that I am working with was originally written in FORTRAN 77. I am hesitant to update all of the files to a more modern standard since there are multiple files thousands of lines long that rely on obsolete functions.
>
> During compilation, I get a few type mismatch arguments, most of which are taken care of with -freal-4-real-8, but I am unsure if that is a permanent solution.

Those are programming errors, and need to be corrected.
There are bound to be errors in FORTRAN programs.

Ron Shepard

unread,
Apr 30, 2020, 10:57:15 AM4/30/20
to
On 4/29/20 6:07 PM, mm2...@scarletmail.rutgers.edu wrote:
> Code at lines 2678-2681:
>
> IF (REENT) THEN REENT = .FALSE. GO TO ROUTE END IF
>
> In the subroutine there is no statement label with the value of 0 which also might contribute to the error. Again, I am hesitant to edit the code too much since it supposedly worked as intended back in the ‘90s. Any help would be greatly appreciated.

If the code is worth the effort, then I would suggest that you fix the
code rather than relying on obscure compiler options to get the correct
results.

As you have figured out, this becomes more difficult if you no longer
have the ability to modify, compile, and test the original code. You
must guess what the old code did, and that can cause all kinds of
obscure downstream errors. So if you still have some combination of old
hardware and software where the code still runs, then add whatever extra
debug print statements are necessary to validate the changed code and
fix the code a statement at a time.

If the code is not worth that effort, then that is a different matter.
Maybe it is easier to maintain the old hardware and software.

$.02 -Ron Shepard

Thomas Koenig

unread,
May 1, 2020, 9:30:14 AM5/1/20
to
mm2...@scarletmail.rutgers.edu <mm2...@scarletmail.rutgers.edu> schrieb:

> The code that I am working with was originally written in
> FORTRAN 77. I am hesitant to update all of the files to a more
> modern standard since there are multiple files thousands of lines
> long that rely on obsolete functions.

Often, there is no need to do a full conversion, getting rid of
a few bugs is often good enough.

What exactly are these "obsolete functions"? Are they non-standard
compiler-supplied intrinsics? If, on the other hand, they are
still in the standard (such as DCOS), I would not worry about them.

Do you know what the original compiler was, and do you have
documentation for it?

> During compilation, I get a few type mismatch arguments, most
> of which are taken care of with -freal-4-real-8, but I am unsure
> if that is a permanent solution.

That can be dangerous, depending on the reason for these mismatches.
If it is just storage allocation (some old Fortran programs have
then), then this may actually work. If it is mismatches... well,
you probably need to look into that.

> I currently use the following flags to compile all of the object
> files which are then compiled into the final executable: -ff2c
> -std=legacy -freal-4-real-8

-ff2c changes the ABI to what f2c did. Is there a particular
reason why you need to do this? I am rather careful about
ABI-altering flags.

> The file in which the error occurs is compiled without the -freal
> flag because it uses a function that requires a real(4) variable.

If you compile one file with one ABI and the other with another ABI,
then you are indeed asking for trouble. It is better not to use
things like -freal-4-real-8 then.

> The current error I am getting upon running the executable is:
> At line 2680 of file twopt.f Fortran runtime error: Assigned label
> is not a target label

So, your program has a bug there.

> The subroutine in which the error occurs takes in REENT as a
> logical parameter. ROUTE is later declared as an integer but is
> not assigned any value which I think might be the reason behind
> the problem. I used print statements to check its value before
> the error occurs, and REENT is true, and ROUTE is 0.

Quesions: Is there any ASSIGN statement in the subroutine?
Are the arguments OK (they very well might not be, due to
flag use)?

>
> Code at lines 2678-2681:
>
> IF (REENT) THEN REENT = .FALSE. GO TO ROUTE END IF

> In the subroutine there is no statement label with the value of
> 0 which also might contribute to the error.

That is not what this is.

An assigned GOTO is a statement like

ASSIGN 100 TO ROUTE

and then later

GOTO ROUTE

which would then jump to

100 CONTINUE

This will not assign the numeric value of 100 to ROUTE. Historically,
this probably put the address of the staement with the number 100
into the variable; gfortran does this a bit differently (using
a shadow variable).

> Again, I am hesitant
> to edit the code too much since it supposedly worked as intended
> back in the ‘90s. Any help would be greatly appreciated.

You should probably understand the code to a degree, at least
where you make changes. You should also try to use all warnings.
Refactoring old code with gfortran, it often (not aways) makes
sense to use -Wall -Werror (and later, -fcheck=all) and then fix
anything that comes up.

JCampbell

unread,
May 1, 2020, 9:51:58 PM5/1/20
to
On Thursday, April 30, 2020 at 9:07:57 AM UTC+10, mm2...@scarletmail.rutgers.edu wrote:
You have not described the hardware used when the FORTRAN 77 code was developed. This should always be documented.

I would not recommend the use of -freal-4-real-8, as it requires any new code changes to be done assuming the old F77 environment. I would change the code to explicitly define the real kind. My preference is to use the non-standard "real*8" as it identifies the type of compiler originally used.
If IMPLICIT NONE was not used, this can be typically be achieved by inserting "IMPLICIT REAL*8(A-H,O-Z)". Changing to IMPLICIT NONE is a good way of documenting the list of variables in use in each routine.

You should also identify any use of constants being used as arguments, as this is not portable. Real constants were never portable. You can replace these with parameters or initialised variables. This now becomes important when 64-bit integers are required, although the mixing of 16-bit and 32-bit integer constants in F77 days did have similar problems.

Also, all COMMONs needs to be checked for variable alignment. It is preferable to move each common into an INCLUDE file (assuming IMPLICIT NONE), to standardise their declaration. Where different types or kind of variables were mixed between different uses of the same labelled common, this can be a significant problem. Frequently this was to move local variables to common to save memory, but could also be to save local variable values between calls. Be careful if this is the case.

ROUTE = 0 must be a code bug.

ga...@u.washington.edu

unread,
May 1, 2020, 10:01:03 PM5/1/20
to
On Wednesday, April 29, 2020 at 4:07:57 PM UTC-7, mm2...@scarletmail.rutgers.edu wrote:

(snip)

> The subroutine in which the error occurs takes in REENT as a
> logical parameter. ROUTE is later declared as an integer but is
> not assigned any value which I think might be the reason behind
> the problem. I used print statements to check its value before
> the error occurs, and REENT is true, and ROUTE is 0.

> Code at lines 2678-2681:

> IF (REENT) THEN REENT = .FALSE. GO TO ROUTE END IF

The tradition, though not at all part of the standard, is that
ASSIGN puts the address of a statement into the variable,
and the GOTO jumps to the statement with that address.

This is just a little bit too convenient for those who want to
write programs that do things like jump to an arbitrary address.

C programs do this by assigning an integer value to a function
pointer variable.



steve kargl

unread,
May 1, 2020, 10:22:04 PM5/1/20
to
JCampbell wrote:

> On Thursday, April 30, 2020 at 9:07:57 AM UTC+10, mm2...@scarletmail.rutgers.edu wrote:
>> The code that I am working with was originally written in FORTRAN 77. I am hesitant to update all of the files to a more modern standard since there are multiple files thousands of lines long that rely on obsolete functions.
>>
>> During compilation, I get a few type mismatch arguments, most of which are taken care of with -freal-4-real-8, but I am unsure if that is a permanent solution.
>>
>> I currently use the following flags to compile all of the object files which are then compiled into the final executable: -ff2c -std=legacy -freal-4-real-8
>>
>> The file in which the error occurs is compiled without the -freal flag because it uses a function that requires a real(4) variable.
>>
>> The current error I am getting upon running the executable is: At line 2680 of file twopt.f Fortran runtime error: Assigned label is not a target label
>>
>> The subroutine in which the error occurs takes in REENT as a logical parameter. ROUTE is later declared as an integer but is not assigned any value which I think might be the reason behind the problem. I used print statements to check its value before the error occurs, and REENT is true, and ROUTE is 0.
>>
>> Code at lines 2678-2681:
>>
>> IF (REENT) THEN REENT = .FALSE. GO TO ROUTE END IF
>>
>> In the subroutine there is no statement label with the value of 0 which also might contribute to the error. Again, I am hesitant to edit the code too much since it supposedly worked as intended back in the ‘90s. Any help would be greatly appreciated.
>
> You have not described the hardware used when the FORTRAN 77 code was developed. This should always be documented.

Yeah, ahem. right. Apparently, you never had a professor hand you a
deck of cards with a request to "make this work". What should be
documented and reality are often two disjoint sets.

> I would not recommend the use of -freal-4-real-8, as it requires any new code changes to be done assuming the old F77 environment. I would change the code to explicitly define the real kind. My preference is to use the non-standard "real*8" as it identifies the type of compiler originally used.

I call BS on this. I've used Fortran on a large selection of hardware and operating systems.
All of the Fortran compilers supported REAL*8. There is no way to correlate a program with
a declaration of REAL*8 with any particular compiler or operating system. In all likelihood,
the proper change, if one is avoiding modern Fortran's kind type parameters, would be to
change REAL*8 to DOUBLE PRECISION.

--
steve

robin....@gmail.com

unread,
May 1, 2020, 10:27:30 PM5/1/20
to
On Friday, May 1, 2020 at 11:30:14 PM UTC+10, Thomas Koenig wrote:
> <m.....@scarletmail.rutgers.edu> schrieb:
>
> > The code that I am working with was originally written in
> > FORTRAN 77. I am hesitant to update all of the files to a more
> > modern standard since there are multiple files thousands of lines
> > long that rely on obsolete functions.
>
> Often, there is no need to do a full conversion, getting rid of
> a few bugs is often good enough.
>
> What exactly are these "obsolete functions"? Are they non-standard
> compiler-supplied intrinsics? If, on the other hand, they are
> still in the standard (such as DCOS), I would not worry about them.
>
> Do you know what the original compiler was, and do you have
> documentation for it?
>
> > During compilation, I get a few type mismatch arguments, most
> > of which are taken care of with -freal-4-real-8, but I am unsure
> > if that is a permanent solution.
>
> That can be dangerous, depending on the reason for these mismatches.
> If it is just storage allocation (some old Fortran programs have
> then), then this may actually work.

On the other hand, they may not.
It depends on the hardware.
On S/360 and later, the formats for single and double precision
are identical except for the least-significant 32 bits of the
mantissa.
Passing a single to a double may pick up arbitrary bits for the
least-significant 32 bits. This may introduce inaccuracies
in the results that may or may not go unnoticed.

Other machines, such as DEC, used different formats for single
an double precision. Garbage results can be produced.

Anyway, such mismatches need to be corrected.

> If it is mismatches... well,
> you probably need to look into that.

Not "probably". Definitely.
Need semicolons to separate those statements.

robin....@gmail.com

unread,
May 1, 2020, 10:32:35 PM5/1/20
to
On Saturday, May 2, 2020 at 11:51:58 AM UTC+10, JCampbell wrote:
> On Thursday, April 30, 2020 at 9:07:57 AM UTC+10, mm2...@scarletmail.rutgers.edu wrote:
> > The code that I am working with was originally written in FORTRAN 77. I am hesitant to update all of the files to a more modern standard since there are multiple files thousands of lines long that rely on obsolete functions.
> >
> > During compilation, I get a few type mismatch arguments, most of which are taken care of with -freal-4-real-8, but I am unsure if that is a permanent solution.
> >
> > I currently use the following flags to compile all of the object files which are then compiled into the final executable: -ff2c -std=legacy -freal-4-real-8
> >
> > The file in which the error occurs is compiled without the -freal flag because it uses a function that requires a real(4) variable.
> >
> > The current error I am getting upon running the executable is: At line 2680 of file twopt.f Fortran runtime error: Assigned label is not a target label
> >
> > The subroutine in which the error occurs takes in REENT as a logical parameter. ROUTE is later declared as an integer but is not assigned any value which I think might be the reason behind the problem. I used print statements to check its value before the error occurs, and REENT is true, and ROUTE is 0.
> >
> > Code at lines 2678-2681:
> >
> > IF (REENT) THEN REENT = .FALSE. GO TO ROUTE END IF
> >
> > In the subroutine there is no statement label with the value of 0 which also might contribute to the error. Again, I am hesitant to edit the code too much since it supposedly worked as intended back in the ‘90s. Any help would be greatly appreciated.
>
> You have not described the hardware used when the FORTRAN 77 code was developed. This should always be documented.
>
> I would not recommend the use of -freal-4-real-8, as it requires any new code changes to be done assuming the old F77 environment. I would change the code to explicitly define the real kind.

> My preference is to use the non-standard "real*8"

This is a bad suggestion. Not only is it non-standard,
it is not portable.

A better alternative is DOUBLE PRECISION.

> as it identifies the type of compiler originally used.

Does it really?

JCampbell

unread,
May 2, 2020, 4:22:12 AM5/2/20
to
I really don't agree with some of the comments, especially regarding the use of "DOUBLE PRECISION". Double what?
Between 1975 and 1990+ I had extensive experience converting between mainframe, mini, workstation and then IBM PC. Certainly mainframe sourced codes, and often from unidentified mainframes, were the most challenging. To get a code that had REAL*8 or INTEGER*2, you had some idea what you were dealing with.
DOUBLE PRECISION from an unknown source was the worst! If it might have come from CDC, then DOUBLE PRECISION could be a game breaker, but perhaps it was IBM or ICL or some other strange word length source but hopefully it was from some early mini that didn't yet support real*8.
Then there is the issue of COMMON alignment. With *byte, you have something to work with. Modern compilers like gFortran's use of fillers for 8-byte type alignment means that there must be care when converting old COMMON with mixing of variable types. This was very often in use to conserve memory. Byte syntax clearly documents the variable/array position and helps with getting a working port. Ever seen "COMMON /NODES/ nn, coord(3,m$nn)" ?

As for Robin's "it is not portable", Steve suggests "All of the Fortran compilers supported REAL*8". If I ever do find a compiler that doesn't support "real*8", I would not use it. You can only imagine what other nasties it would have.
Then, what do you do when the (F90) code provided does not include the precision definition module ? Compilers do provide a key module and include file directory for system related info, so often these are omitted from the supplied code. I have had missing system related info often.

For a successful port, the aim is to change the code with the minimal number of changes, although IMPLICIT NONE or an equivalent compiler option was a good first start. Approaches like using -freal-4-real-8 are likely to miss some of the others problems. It is better to spend a few hours/days now identifying problems, rather than weeks later when the new code doesn't work and results are required.

( Not yet discussed pre F90 memory management tricks or pre F77 character tricks. Best forgotten...but they might be in this FORTRAN 77 code )

robin....@gmail.com

unread,
May 2, 2020, 8:37:01 AM5/2/20
to
I think you mean, change REAL and REAL*4 to DOUBLE PRECISION.

robin....@gmail.com

unread,
May 2, 2020, 8:55:30 AM5/2/20
to
On Saturday, May 2, 2020 at 6:22:12 PM UTC+10, JCampbell wrote:
> I really don't agree with some of the comments, especially regarding the use of "DOUBLE PRECISION". Double what?

The FORTRAN standard is absolutely clear on this. DOUBLE PRECISION
has more precision than REAL (i.e., single precision).

> Between 1975 and 1990+ I had extensive experience converting between mainframe, mini, workstation and then IBM PC. Certainly mainframe sourced codes, and often from unidentified mainframes, were the most challenging. To get a code that had REAL*8 or INTEGER*2, you had some idea what you were dealing with.
> DOUBLE PRECISION from an unknown source was the worst! If it might have come from CDC, then DOUBLE PRECISION could be a game breaker, but perhaps it was IBM or ICL or some other strange word length source but hopefully it was from some early mini that didn't yet support real*8.
> Then there is the issue of COMMON alignment. With *byte, you have something to work with. Modern compilers like gFortran's use of fillers for 8-byte type alignment means that there must be care when converting old COMMON with mixing of variable types. This was very often in use to conserve memory. Byte syntax clearly documents the variable/array position and helps with getting a working port. Ever seen "COMMON /NODES/ nn, coord(3,m$nn)" ?
>
> As for Robin's "it is not portable", Steve suggests "All of the Fortran compilers supported REAL*8". If I ever do find a compiler that doesn't support "real*8", I would not use it.

No-one is forcing you to use modern Fortran.

REAL*8 is not standard. That means, "not standard".

> You can only imagine what other nasties it would have.

> Then, what do you do when the (F90) code provided does not include the precision definition module ? Compilers do provide a key module and include file directory for system related info, so often these are omitted from the supplied code. I have had missing system related info often.

Well, then, you don't have the complete program.

> For a successful port, the aim is to change the code with the minimal number of changes,

The aim is to fix the errors where arguments and dummy arguments
do not match.

Then, it may be necessary to change certain single-precision constants
to double-precision constants in order to avoid losing accuracy.

> although IMPLICIT NONE or an equivalent compiler option was a good first start.

IMPLICIT NONE is not relevant in this case. The issue is to remove
the errors relating to "mismatched arguments".

Incorporating IMPLICIT NONE may require extensive source changes, which
of itself may introduce further errors.

Phillip Helbig (undress to reply)

unread,
May 2, 2020, 9:00:15 AM5/2/20
to
In article <6ab417ef-5bd2-40fc...@googlegroups.com>,
robin....@gmail.com writes:

> On Saturday, May 2, 2020 at 6:22:12 PM UTC+10, JCampbell wrote:
> > I really don't agree with some of the comments, especially regarding the =
> use of "DOUBLE PRECISION". Double what?
>
> The FORTRAN standard is absolutely clear on this. DOUBLE PRECISION
> has more precision than REAL (i.e., single precision).

Doesn't it also have exactly twice the storage? Certainly in most
implementations that is the case, but I think that it is also required.

Whether or not the PRECISION is double is another question---probably
not in both cases. Note that some systems had different types of
double-wide data, one with more bits in the exponent, one with more in
the mantissa. One of these was the default for DOUBLE PRECISION, but
compiler options could change that.

steve kargl

unread,
May 2, 2020, 11:29:38 AM5/2/20
to
JCampbell wrote:

> As for Robin's "it is not portable", Steve suggests "All of the Fortran compilers supported REAL*8".
> If I ever do find a compiler that doesn't support "real*8", I would not use it. You can only imagine
> what other nasties it would have.

Please, learn to properly quote others' post. By cherry picking a single sentence
from my post, you're suggesting that I believe that all Fortran compilers ever
written supported REAL*8. That sentence indeed appeared my post, except
it now appears without context. Here the crucial missing quote:

>>You wrote:
>>
>> I would not recommend the use of -freal-4-real-8, as it requires
>> any new code changes to be done assuming the old F77 environment.
>> I would change the code to explicitly define the real kind. My
>> preference is to use the non-standard "real*8" as it identifies
>> the type of compiler originally used.
>
> My reply:
> I've used Fortran on a large selection of hardware and operating systems.
> All of the Fortran compilers supported REAL*8. There is no way to correlate
> a program with a declaration of REAL*8 with any particular compiler or
> operating system.
>

I standby my assertion that you cannot "identif[y] the type of compiler
originally used." simply because the code contained REAL*8

--
steve


robin....@gmail.com

unread,
May 2, 2020, 1:05:30 PM5/2/20
to
On Saturday, May 2, 2020 at 11:00:15 PM UTC+10, Phillip Helbig (undress to reply) wrote:
> In article <6......@googlegroups.com>,
> r......@gmail.com writes:
>
> > On Saturday, May 2, 2020 at 6:22:12 PM UTC+10, JCampbell wrote:
> > > I really don't agree with some of the comments, especially regarding the =
> > use of "DOUBLE PRECISION". Double what?
> >
> > The FORTRAN standard is absolutely clear on this. DOUBLE PRECISION
> > has more precision than REAL (i.e., single precision).
>
> Doesn't it also have exactly twice the storage?

It must be exactly two storage units.
INTEGER, REAL, LOGICAL count as one storage unit.

This relationship is essential for COMMON to work properly.

> Certainly in most
> implementations that is the case, but I think that it is also required.
>
> Whether or not the PRECISION is double is another question---probably
> not in both cases.

Precision is not necessarily double the precision of a single precision
item. Typically, it is more than double. Where it might be exactly
double the precision of a single could occur of the second storage unit
was the same format as the first storage unit, and contained an exponent
field as well.

> Note that some systems had different types of
> double-wide data, one with more bits in the exponent, one with more in
> the mantissa. One of these was the default for DOUBLE PRECISION, but
> compiler options could change that.

Yes, DEC systems are an example.

robin....@gmail.com

unread,
May 2, 2020, 1:08:40 PM5/2/20
to
Some of the better-documented FORTRAN programs included the name
and model of the computer on which the program originated.

COBOL programs do this.

Ron Shepard

unread,
May 2, 2020, 2:04:30 PM5/2/20
to
On 5/1/20 8:51 PM, JCampbell wrote:
> I would not recommend the use of -freal-4-real-8, as it requires any new code changes to be done assuming the old F77 environment. I would change the code to explicitly define the real kind. My preference is to use the non-standard "real*8" as it identifies the type of compiler originally used.
> If IMPLICIT NONE was not used, this can be typically be achieved by inserting "IMPLICIT REAL*8(A-H,O-Z)". Changing to IMPLICIT NONE is a good way of documenting the list of variables in use in each routine.

I would not recommend using IMPLICIT REAL*8(A-H,O-Z) these days. That
was a reasonable approach back when f77 didn't allow anything better,
but now we have KINDs, which solves all of those problems with both
variables and literal constants.

However, this does lead to the question of why something like

IMPLICIT REAL(KIND=WP)(A-H,O-Z)

or something equivalent was never standardized. Anyone know why not? Was
it just the general feeling that implicit typing was a bad approach to
programming and they didn't want to encourage it?

$.02 -Ron Shepard

Gary Scott

unread,
May 2, 2020, 2:24:09 PM5/2/20
to
On 5/2/2020 3:22 AM, JCampbell wrote:
> I really don't agree with some of the comments, especially regarding the use of "DOUBLE PRECISION". Double what?
> Between 1975 and 1990+ I had extensive experience converting between mainframe, mini, workstation and then IBM PC. Certainly mainframe sourced codes, and often from unidentified mainframes, were the most challenging. To get a code that had REAL*8 or INTEGER*2, you had some idea what you were dealing with.
> DOUBLE PRECISION from an unknown source was the worst! If it might have come from CDC, then DOUBLE PRECISION could be a game breaker, but perhaps it was IBM or ICL or some other strange word length source but hopefully it was from some early mini that didn't yet support real*8.


Harris minis (H series) were 24 bit. They supported real*6, real*12

Ron Shepard

unread,
May 2, 2020, 2:41:19 PM5/2/20
to
On 5/1/20 9:32 PM, robin....@gmail.com wrote:
>> My preference is to use the non-standard "real*8"
> This is a bad suggestion. Not only is it non-standard,
> it is not portable.
>
> A better alternative is DOUBLE PRECISION.

Most of these arguments now are moot since we have the KIND facility in
fortran. However, I would say that in the 1970s and 1980s, DOUBLE
PRECISION was standard, but it didn't always do what you wanted, while
REAL*8 was portable and did what you wanted, but was nonstandard. So
programmers were between a rock and a hard place choosing between the
two, either standard conforming or portable, but not both. Combine that
with the lack of a preprocessor as part of the language standard, the
pitfalls that came with 72-column statement lengths that prevented
simple text substitutions between REAL and DOUBLE PRECISION, the lack of
IMPLICIT NONE, the lack of INCLUDE, and programmers were screwed over by
the language every which way.

This was partly by design, of course, vendors did not want to make it
easy for programmers to port their codes to competitor's hardware, they
wanted to lock in their customers as much as possible.

We still, four+ decades later, do not have a standard preprocessor
defined as part of the language. I truly do not understand that. Yes, we
have the de facto C preprocessor that everyone uses, but it does have
its quirks. But at least we have IMPLICIT NONE and INCLUDE now. And we
have the KIND facility in fortran, they got that part right. It could be
a little smoother here and there (e.g. unique KINDs over all types would
have been nice), but the basic approach is right.

$.02 -Ron Shepard


James Van Buskirk

unread,
May 2, 2020, 2:53:31 PM5/2/20
to
"Ron Shepard" wrote in message news:MCirG.119322$Ff6....@fx40.iad...

> However, this does lead to the question of why something like

> IMPLICIT REAL(KIND=WP)(A-H,O-Z)

> or something equivalent was never standardized. Anyone know why not? Was
> it just the general feeling that implicit typing was a bad approach to
> programming and they didn't want to encourage it?

I don't understand the question:

D:\gfortran\clf\bitrev>type implicit.f90
program stuff
use ISO_FORTRAN_ENV, only: wp=>REAL64
implicit real(KIND=wp) (a-h,o-z)
write(*,*) kind(x), kind(1.0), kind(1.0d0)
end program stuff

D:\gfortran\clf\bitrev>gfortran implicit.f90 -oimplicit -std=f2008

D:\gfortran\clf\bitrev>implicit
8 4 8

ga...@u.washington.edu

unread,
May 2, 2020, 6:39:20 PM5/2/20
to
On Saturday, May 2, 2020 at 11:24:09 AM UTC-7, Gary Scott wrote:


(snip regarding REAL*8)

> Harris minis (H series) were 24 bit. They supported real*6, real*12

The PDP-10 compilers support REAL*8 for the 72 bit form.

How big is default INTEGER on the Harris?

I do remember many Fortran compilers for 16 bit minicomputers
used 16 bit default INTEGER and 32 bit default REAL, though possibly
a compiler option to force the INTEGER to 32 bits. (But even in the
latter case, I believe only 16 bits were used in computation.)



ga...@u.washington.edu

unread,
May 2, 2020, 6:53:11 PM5/2/20
to
On Friday, May 1, 2020 at 7:22:04 PM UTC-7, steve kargl wrote:

(snip)

> I call BS on this. I've used Fortran on a large selection of
> hardware and operating systems.
> All of the Fortran compilers supported REAL*8.
> There is no way to correlate a program with a declaration of
> REAL*8 with any particular compiler or operating system.

I believe in the punched card days, I used REAL*8 because it was
faster and more reliable to punch. Remember with cards, if you make
a keypunch error, you can't just backspace and put in the right character
(unless it was a blank), but instead start a new card.

I am not completely sure now, with the shift required for the *,
that it was easier, though.

> In all likelihood, the proper change, if one is avoiding modern
> Fortran's kind type parameters, would be to
> change REAL*8 to DOUBLE PRECISION.

Pretty much everyone else wanted to be compatible with IBM, so
that people could easily port to theirs. On the other hand, many had
features that IBM didn't, to make porting away harder.

IBM was somewhat limited in the extensions that they supported.
Some easy ones, like DO loops that start at 0 or have negative
increments they didn't have, but harder ones, like NAMELIST they did.

But also, 16 bit minicomputers needed a way to allow for both 16 bit
and 32 bit integers, so support for INTEGER*2 and INTEGER*4 was used.

The DEC compilers I remember used BYTE instead of INTEGER*1, though.
(I might have forgotten that one.)

While many supported REAL*8, not so many had COMPLEX*16.

In any case, REAL*8 is likely more portable, but less standard,
than the way too common REAL(8).

I suppose I don't mind people using REAL(8) in programs that others
won't see, but I know of people teaching computational physics
courses that use REAL(8).

And yes, as someone else mentioned, it is nice to not overlap the
KIND values for REAL and INTEGER. That invites too many strange errors.




JCampbell

unread,
May 2, 2020, 8:49:29 PM5/2/20
to
On Sunday, May 3, 2020 at 1:29:38 AM UTC+10, steve kargl wrote:
If "all Fortran compilers ever written supported REAL*8" it would be a different discussion ! CDC, IBM and most UK hardware of the time had other ideas. It was the 32-bit mini in the early 70's that changed everything and gave us easier access to FORTRAN. That is why we wanted to port away from those other non-real*8 types. I did do ports to IBM and to ICL around 1980 which were a challenge. This experience cemented my view of those architectures and their compiler approach. Remember the term "processor-dependent" that is spread liberally through the F77 standard ?

When referring to the "type", I was attempting to say, if it used "real*8" it probably was a 32-bit compiler of 70's or 80's that supported 8-bit bytes. This should be an easy conversion, as few ports were to other types of computers. Alternatively, if it was a compiler type that supported other formats, like real*6, real*12 with unknown byte size, then you were going to have a much bigger problem.

Although generic intrinsics were introduced in F77, there were still a lot of programmers that persisted with the pre-F77 syntax, such as FLOAT, IFIX, MAX0, ALOG or DSIN which are now not so familiar.

ga...@u.washington.edu

unread,
May 2, 2020, 9:13:58 PM5/2/20
to
On Saturday, May 2, 2020 at 5:49:29 PM UTC-7, JCampbell wrote:

(snip)

> If "all Fortran compilers ever written supported REAL*8" it
> would be a different discussion ! CDC, IBM and most UK hardware
> of the time had other ideas. It was the 32-bit mini in the
> early 70's that changed everything and gave us easier access
> to FORTRAN. That is why we wanted to port away from those
> other non-real*8 types. I did do ports to IBM and to ICL
> around 1980 which were a challenge. This experience cemented
> my view of those architectures and their compiler approach.
> Remember the term "processor-dependent" that is spread
> liberally through the F77 standard ?

The 36 bit DEC 36 bit PDP-10 compilers, and the 16 bit PDP-11
compilers support REAL*8, so it doesn't have much to do with 32 bit.
The PDP-11 compilers default to INTEGER*2 for plain INTEGER, but
go to INTEGER*4 with a compiler option.

Gary Scott

unread,
May 2, 2020, 9:17:19 PM5/2/20
to
On 5/2/2020 5:39 PM, ga...@u.washington.edu wrote:
> On Saturday, May 2, 2020 at 11:24:09 AM UTC-7, Gary Scott wrote:
>
>
> (snip regarding REAL*8)
>
>> Harris minis (H series) were 24 bit. They supported real*6, real*12
>
> The PDP-10 compilers support REAL*8 for the 72 bit form.
>
> How big is default INTEGER on the Harris?


INTEGER*3

Gary Scott

unread,
May 2, 2020, 9:21:14 PM5/2/20
to
On 5/2/2020 8:17 PM, Gary Scott wrote:
> On 5/2/2020 5:39 PM, ga...@u.washington.edu wrote:
>> On Saturday, May 2, 2020 at 11:24:09 AM UTC-7, Gary Scott wrote:
>>
>>
>> (snip regarding REAL*8)
>>
>>> Harris minis (H series) were 24 bit.  They supported real*6, real*12
>>
>> The PDP-10 compilers support REAL*8 for the 72 bit form.
>>
>> How big is default INTEGER on the Harris?
>
>
> INTEGER*3

Some operations worked on 48 bits, such as memory transfers, so in some
sense they were hybrid 24/48 bit computers, depending on operation.

robin....@gmail.com

unread,
May 3, 2020, 1:17:11 AM5/3/20
to
On Sunday, May 3, 2020 at 4:41:19 AM UTC+10, Ron Shepard wrote:
> On 5/1/20 9:32 PM, r......@gmail.com wrote:
> >> My preference is to use the non-standard "real*8"
> > This is a bad suggestion. Not only is it non-standard,
> > it is not portable.
> >
> > A better alternative is DOUBLE PRECISION.
>
> Most of these arguments now are moot since we have the KIND facility in
> fortran.

In the context of the OP's problem, DOUBLE PRECISION is the best
option, as it requires minimal source change to the FORTRAN 77 source.

> However, I would say that in the 1970s and 1980s, DOUBLE
> PRECISION was standard, but it didn't always do what you wanted, while
> REAL*8 was portable

It wasn't portable. and it is still not standard.

> and did what you wanted,

No it didn't.

> but was nonstandard. So
> programmers were between a rock and a hard place choosing between the
> two, either standard conforming or portable, but not both. Combine that
> with the lack of a preprocessor as part of the language standard, the
> pitfalls that came with 72-column statement lengths that prevented
> simple text substitutions between REAL and DOUBLE PRECISION, the lack of
> IMPLICIT NONE, the lack of INCLUDE, and programmers were screwed over by
> the language every which way.
>
> This was partly by design, of course, vendors did not want to make it
> easy for programmers to port their codes to competitor's hardware, they
> wanted to lock in their customers as much as possible.

Alas, true.

robin....@gmail.com

unread,
May 3, 2020, 1:24:15 AM5/3/20
to
On Sunday, May 3, 2020 at 8:53:11 AM UTC+10, ga...@u.washington.edu wrote:
> On Friday, May 1, 2020 at 7:22:04 PM UTC-7, steve kargl wrote:
>
> (snip)
>
> > I call BS on this. I've used Fortran on a large selection of
> > hardware and operating systems.
> > All of the Fortran compilers supported REAL*8.
> > There is no way to correlate a program with a declaration of
> > REAL*8 with any particular compiler or operating system.
>
> I believe in the punched card days, I used REAL*8 because it was
> faster and more reliable to punch. Remember with cards, if you make
> a keypunch error, you can't just backspace and put in the right character
> (unless it was a blank), but instead start a new card.

But you could COPY the card up to the wrong column, and then
type the correct character or characters.

If there was an omitted character, you could copy up to the
appropriate column, type the character to be inserted (while holding
the original card in place), and then copy the balance of the card.

ga...@u.washington.edu

unread,
May 3, 2020, 6:37:31 AM5/3/20
to
On Saturday, May 2, 2020 at 10:24:15 PM UTC-7, robin...@gmail.com wrote:

(snip, I wrote)

> > I believe in the punched card days, I used REAL*8 because it was
> > faster and more reliable to punch. Remember with cards, if you make
> > a keypunch error, you can't just backspace and put in the right character
> > (unless it was a blank), but instead start a new card.

> But you could COPY the card up to the wrong column, and then
> type the correct character or characters.

You could, but if I mispunched REAL*8 and figured it out
immediately, I would probably redo the whole thing instead
of copying it. It isn't that long.

robin....@gmail.com

unread,
May 3, 2020, 8:22:29 AM5/3/20
to
That's rather obvious.

Ron Shepard

unread,
May 3, 2020, 2:13:00 PM5/3/20
to
You are right, I overlooked this, it is standard. I thought it was just
an extension.

$.02 -Ron Shepard

Ron Shepard

unread,
May 3, 2020, 2:57:26 PM5/3/20
to
On 5/3/20 12:17 AM, robin....@gmail.com wrote:
>> Most of these arguments now are moot since we have the KIND facility in
>> fortran.
> In the context of the OP's problem, DOUBLE PRECISION is the best
> option, as it requires minimal source change to the FORTRAN 77 source.

That cannot be known from just what the OP stated. If his original f77
style code came from a Cray or one of the several other machines in
which REAL meant 60-bit or 64-bit and DOUBLE PRECISION meant twice that,
then your statement would not be correct.

>> However, I would say that in the 1970s and 1980s, DOUBLE
>> PRECISION was standard, but it didn't always do what you wanted, while
>> REAL*8 was portable
> It wasn't portable. and it is still not standard.

That is your opinion, and you are entitled to it, but you are still
wrong about the portability part.

>
>> and did what you wanted,
> No it didn't.

It did, and that is exactly why the REAL*8 declarations were so popular
in the 1970s and 1980s. It would almost always map onto whatever
hardware you had the way you wanted it to. I mentioned Cray above -- on
the Cray the declaration would map onto their REAL 64-bit data type,
which is almost always what the programmer wanted; I would say it was
rare that a programmer wanted REAL*8 to map onto DOUBLE PRECISION
128-bit floating point on a Cray. But there were many other machines,
with 60-bit words, 24-bit words, 36-bit words (IBM, UNIVAC, DEC) for
which this mapping also worked the way you wanted.

Someone else mentioned Harris with 24, 48, and 96-bit data types, there
was even a way to map REAL*8 declarations onto those machines in a
portable way without changing the source code. I remember I had more
problems on a Harris with their convention that the 8th bit was always
on in characters than I did with the unusual word length. If you edited
a text file without this convention, all the characters would display
and print correctly, but the compiler and many of the other utility
codes would fail to work. There was a "force8" utility that would
convert the 8th bit from 0 to 1 in all bytes -- that solved lots of
head-scratching problems.

$.02 -Ron Shepard

Ron Shepard

unread,
May 3, 2020, 3:43:50 PM5/3/20
to
There was a time in the mid 1970s when I was transferring code among IBM
(32-64 bit), UNIVAC (36-72 bit), and DEC (36-72 bit) computers daily.
Anything I wrote needed to compile immediately with no change on all
three machines. I quickly figured out that REAL*8 was the way to go.
Then just a couple of years later, I had to port all that code to Harris
(24-48-96 bit) and CDC (60 bit) computers. REAL*8 worked there too. Then
a couple of years after that, all that code went onto VAX (32-64 bit),
Cray (64 bit), FPS (64 bit), and ETA (32-64 bit) hardware. REAL*8 worked
there too. Then came all of the RISC workstations in the 1980s, about a
dozen of them, and sure enough, REAL*8 declarations worked there too.

I also wrote (in fortran, of course) utility codes that would convert my
fortran codes to standard fortran (REAL and DOUBLE PRECISION
declarations), but this approach was always awkward because of the
72-character statement length limit. But this did allow at least a
one-way conversion of codes onto hardware that did not support REAL*8
declarations cleanly. But going backward, from REAL to REAL*8, was
problematic because there were always cases where REAL meant REAL that
had to be treated specially. This conversion step also included changing
between D* and S* BLAS, LINPACK, and later LAPACK calls -- those were a
PITA, but at least they were relatively straightforward text substitutions.

All this was particularly frustrating in the 1980s because I was
following the fortran 8x standard process, so I knew about the upcoming
KIND capability, the standard bit operators, and the ability to write
generic interfaces, all of which would have solved many of my
portability issues cleanly. But that would not help matters in a
practical way until the mid to late 1990s, a decade later when f90 and
later compilers finally began to become available.

$.02 -Ron Shepard

ga...@u.washington.edu

unread,
May 3, 2020, 3:45:06 PM5/3/20
to
On Sunday, May 3, 2020 at 11:57:26 AM UTC-7, Ron Shepard wrote:
> On 5/3/20 12:17 AM, robin....@gmail.com wrote:
> >> Most of these arguments now are moot since we have the KIND facility in
> >> fortran.
> > In the context of the OP's problem, DOUBLE PRECISION is the best
> > option, as it requires minimal source change to the FORTRAN 77 source.

> That cannot be known from just what the OP stated. If his original f77
> style code came from a Cray or one of the several other machines in
> which REAL meant 60-bit or 64-bit and DOUBLE PRECISION meant twice that,
> then your statement would not be correct.

OK, what the OP actually said is:

"During compilation, I get a few type mismatch arguments,
most of which are taken care of with -freal-4-real-8,
but I am unsure if that is a permanent solution"

I suspect that there might be real bugs that should be found,
especially since it says "few".

It might be warnings assigning to double precision variables like:

X = 1.0

or

X = 1.1

which should be fixed, but aren't really big problems.

Calling subroutines with the wrong constant type is a big problem
that should be fixed, instead of patched over.

If you see:

IMPLICIT REAL*8 (A-H, O-$)

you are most likely working with IBM Fortran IV source, which
uses a 27 letter alphabet.

Well, VAX needed $ in their alphabet, as many VMS system calls have
a $ in their name, but I don't remember seeing it in IMPLICIT in VAX
source.

In any case, the OP should try to understand the actual problem.

FortranFan

unread,
May 3, 2020, 5:01:32 PM5/3/20
to
On Sunday, May 3, 2020 at 3:45:06 PM UTC-4, ga...@u.washington.edu wrote:

> ..
> OK, what the OP actually said is:
>
> ..
> I suspect that there might be real bugs that should be found,
> especially since it says "few".
>
> ..
> In any case, the OP should try to understand the actual problem.


Well, OP is yet to respond to any of the replies on this thread. So this matter does not seem to be of much interest or urgency to OP.

JCampbell

unread,
May 3, 2020, 9:56:42 PM5/3/20
to
I am surprised there was a Harris F77 compiler that supported INTEGER*3 / REAL*6.
Would it have been released in 80's so to have a 24 bit based computer must have been something different? How long did it last? (Apparently it also supported INTEGER*6, which was something in 1980, see https://www.tug.org/TUGboat/tb03-2/tb06mbj.pdf )
I found one link in Google to https://scitools.com/feature/supported-languages/ This referenced DEC and HARRIS extensions as being a thing.
Also a link to Federal Software testing centre. The summary includes "an overview of the validation which lists all categories of discrepancies together with the tests which failed."
There was another link to HARRIS F77 Documentation, but the link didn't work, so google no longer shows it.

DEC Fortran extensions are another interesting aspect of porting. It was always a bridge too far for me to use, as the huge number of extensions produced a code that could become very difficult to port. I way under-quoted the first and only time ported from a DEC and we had a VAX 780 in house (for Intergraph only). When I needed a record structure, I generated it in a COMMON and then grouped it with a record name using EQUIVALENCE.

In the 70's and 80's REAL*8 and then F77 intrinsic functions were the portable approach, so I was very disappointed when it was not included in the F77 or F90 standard. Claims "It wasn't portable" are from a different computing environment to my experience.
Then again, I stopped using mainframes by 1975 after the Prime was installed in the computer lab. We transitioned from a university mainframe to every engineering department with their own Prime or Vax mini and as we left Uni, Fortran usage exploded.

Interestingly, most mini computers were based on INTEGER*2 and REAL*4, so default integer and real were not the same word size.

ga...@u.washington.edu

unread,
May 4, 2020, 12:09:45 AM5/4/20
to
On Sunday, May 3, 2020 at 6:56:42 PM UTC-7, JCampbell wrote:

(snip)

> Interestingly, most mini computers were based on INTEGER*2 and
> REAL*4, so default integer and real were not the same word size.

That is true for the DEC PDP-11 compilers, but I believe that
a compiler option will make the default INTEGER*4. So, yes,
it is non-standard without that option.



0 new messages