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

Variable values after READ encounters errors

243 views
Skip to first unread message

Beliavsky

unread,
Mar 26, 2022, 8:06:41 AM3/26/22
to
In section 10.7 of Metcalf/Reid/Cohen (2018), they write, "If an error or end-of-file condition occurs on input, the statement terminates and all list items and any implied-do variables become undefined."

Although gfortran, g95, ifort, and flang all say that i is 42 and j is 8 at the end of the following code, I believe the Fortran standard does not mandate this. Correct?

program main
implicit none
character (len=100) :: text
integer :: i,j,ierr
text = "42 abc"
i = 7
j = 8
read (text,*,iostat=ierr) i,j
print*,"ierr, i, j =",ierr,i,j
end program main

Thomas Koenig

unread,
Mar 26, 2022, 9:26:09 AM3/26/22
to
Beliavsky <beli...@aol.com> schrieb:

> In section 10.7 of Metcalf/Reid/Cohen (2018), they write, "If
> an error or end-of-file condition occurs on input, the statement
> terminates and all list items and any implied-do variables become
> undefined."

Unsurprisingly, the authors are right. And I quote:

12.11.2 Error conditions and the ERR= specifier

[...]

If an error condition occurs during execution of an input/output
statement that contains either an ERR= specifier or an IOSTAT=
specifier then:

[...]

(2) if the statement is a data transfer statement or the error
condition occurs during a wait operation, all do-variables in the
statement that initiated the transfer become undefined;

[...]

(6) if the statement is a data transfer statement or the error
condition occurs during a wait operation, all do-variables in the
statement that initiated the transfer become undefined;

> Although gfortran, g95, ifort, and flang all say that i is 42
> and j is 8 at the end of the following code, I believe the Fortran
> standard does not mandate this. Correct?

Correct. There is a fine difference between "works when tested" and
"advertised as working in extension to the standard". Any compiler
might have chosen to document this behavior (gfortran didn't), then
it would be possible to rely on it for that particular compiler,
but it would be non-portable. As is, the behavior might change
with a new version, a different optimization option, or (somewhat
unlikely) the phase of the moon.

Beliavsky

unread,
Mar 26, 2022, 9:42:25 AM3/26/22
to
Since all the compilers I have tested update the variables that can be read
and preserve the old values of the variable that cannot be read, and since this
behavior may be what the user wants, would it make sense to add a PRESERVE
specifier to the READ statement? With PRESERVE=.TRUE. the current behavior
would be mandated.

Thomas Koenig

unread,
Mar 26, 2022, 3:17:27 PM3/26/22
to
Beliavsky <beli...@aol.com> schrieb:

> Since all the compilers I have tested update the variables that can be read
> and preserve the old values of the variable that cannot be read, and since this
> behavior may be what the user wants, would it make sense to add a PRESERVE
> specifier to the READ statement? With PRESERVE=.TRUE. the current behavior
> would be mandated.

The tradition of Fortran is to use strings for I/O, such as
ADVANCE="NO". Of course, your proposal could be amended for that.

It would also be necessary to specify what happens for asynchronous
I/O.

If a compiler has a different way of doing I/O that makes this hard,
such a provision would force that compiler to a) change that method,
and b) to make it selectable at run-time - a user might specify
a string (or that would have to be disallowed.

If a user wants that effect, it is probably better to use
individual I/O statements. Stream I/O and non-advancing I/O
should offer enough possibilities to do this. Or, it is also
possible to specify something like

read (unit,fmt,iostat=ios) tmp
if (ios == 0) a = tmp

Beliavsky

unread,
Mar 26, 2022, 3:42:25 PM3/26/22
to
Thanks for your comments and code. The safe way of writing my original code is

program main
implicit none
character (len=100) :: text
integer :: i,j,itmp,jtmp,ierr
text = "42 abc"
i = 7
j = 8
! try to read two integers
read (text,*,iostat=ierr) itmp,jtmp
if (ierr == 0) then
i = itmp
j = jtmp
else ! try to read one integer
read (text,*,iostat=ierr) itmp
if (ierr == 0) i = itmp
end if
print*,"i, j =",i,j
end program main
! output with gfortran, g95, ifort, and flang
! i, j = 42 8

gah4

unread,
Mar 26, 2022, 9:25:11 PM3/26/22
to
On Saturday, March 26, 2022 at 12:17:27 PM UTC-7, Thomas Koenig wrote:
> Beliavsky <beli...@aol.com> schrieb:

(snip)

I first learned about this almost 40 years ago on VAX. I wanted to use
the implied-DO variable to find out how many were read before END=.
I was close to sending a bug report, though I had never seen an actual
copy of the standard. It might be that the DEC manual documented
this, though.

> The tradition of Fortran is to use strings for I/O, such as
> ADVANCE="NO". Of course, your proposal could be amended for that.

> It would also be necessary to specify what happens for asynchronous
> I/O.

> If a compiler has a different way of doing I/O that makes this hard,
> such a provision would force that compiler to a) change that method,
> and b) to make it selectable at run-time - a user might specify
> a string (or that would have to be disallowed.

C's scanf() family has no error modes.

It is defined such that successfully read values are guaranteed to be
stored, and ones that haven't been reached are guaranteed unchanged.
(I am not so sure about asynchronous I/O, but I don't think scanf()
does that.)

Note that there are no conversion errors in C. Formatted I/O for
numeric descriptors ends without error when a character that
can't be used is found, and that character is left for the next
I/O operation to read.

scanf() returns the number of successful read items,
including the number read before EOF.

> If a user wants that effect, it is probably better to use
> individual I/O statements. Stream I/O and non-advancing I/O
> should offer enough possibilities to do this. Or, it is also
> possible to specify something like

Since Fortran stream I/O was designed based on C, it would seem
reasonable for it to follow C's rules, when possible.

Robin Vowels

unread,
Mar 26, 2022, 10:27:52 PM3/26/22
to
On Saturday, March 26, 2022 at 11:06:41 PM UTC+11, Beliavsky wrote:
> In section 10.7 of Metcalf/Reid/Cohen (2018), they write, "If an error or end-of-file condition occurs on input, the statement terminates and all list items and any implied-do variables become undefined."
>
> Although gfortran, g95, ifort, and flang all say that i is 42 and j is 8 at the end of the following code, I believe the Fortran standard does not mandate this. Correct?
.
Undefined means "undefined".
It doesn't matter what values the variables have, they are still undefined
and you cannot use them.
.

Beliavsky

unread,
Mar 27, 2022, 1:12:01 PM3/27/22
to
On Saturday, March 26, 2022 at 9:42:25 AM UTC-4, Beliavsky wrote:
> Since all the compilers I have tested update the variables that can be read
> and preserve the old values of the variable that cannot be read, and since this
> behavior may be what the user wants, would it make sense to add a PRESERVE
> specifier to the READ statement? With PRESERVE=.TRUE. the current behavior
> would be mandated.

A further suggestion. When reading an array from a string, the returned IOSTAT
tells you whether or not the entire array could be read, but it would be nice to know
how many of the array elements could be read. An NREAD specifier returning an
integer could be used for this. Since a READ statement may have multiple scalar
and array items, the NREAD would correspond to the last item in the list. If it is a
scalar, NREAD would be 1 if the scalar were read, otherwise 0. As demonstrated at
https://github.com/Beliavsky/FortranTip/blob/main/iomsg.f90 , IOMSG from gfortran
currently gives an informative message saying which item in a list could not be read,
but the IOMSG from Intel Fortran does not provide this information.

Fortran 202x will have SPLIT intrinsics. One can split lines into strings and read
individual items from them.

Robin Vowels

unread,
Mar 28, 2022, 8:43:49 AM3/28/22
to
.
I can't believe that this discussion is still raging after 50 years.
.
If you want these facilities, use PL/I. which stores those values that
were read in, and leaves unchanged those variables for which
a value could not be read in on account of some error or whatever.
.
PL/I even provides a variable (COUNT) that tells you the
number of values that were successfully read and stored.
.
We have been using these PL/I facilities for 55 years.

Beliavsky

unread,
Mar 28, 2022, 9:50:52 AM3/28/22
to
On Monday, March 28, 2022 at 8:43:49 AM UTC-4, Robin Vowels wrote:

> If you want these facilities, use PL/I. which stores those values that
> were read in, and leaves unchanged those variables for which
> a value could not be read in on account of some error or whatever.
> .
> PL/I even provides a variable (COUNT) that tells you the
> number of values that were successfully read and stored.
> .
> We have been using these PL/I facilities for 55 years.

Robin,
I think programming languages sometimes become so unpopular and
unsupported that they are not viable, regardless of their intrinsic merits.
Some say this about Fortran, but I hope they are wrong. I think it is true
of PL/1. You have been educating us about Pl/I for years (decades?. More
than one millennium?) Besides the Wikipedia article, what are the best
online resources in your opinion? Maybe reading them would give
Fortranners some ideas.

gah4

unread,
Mar 28, 2022, 3:31:15 PM3/28/22
to
On Monday, March 28, 2022 at 6:50:52 AM UTC-7, Beliavsky wrote:

(snip)

> > We have been using these PL/I facilities for 55 years.

Possibly with a 55 year old compiler.


> Robin,
> I think programming languages sometimes become so unpopular and
> unsupported that they are not viable, regardless of their intrinsic merits.
> Some say this about Fortran, but I hope they are wrong. I think it is true
> of PL/1. You have been educating us about Pl/I for years (decades?. More
> than one millennium?) Besides the Wikipedia article, what are the best
> online resources in your opinion? Maybe reading them would give
> Fortranners some ideas.

I was doing both Fortran and PL/I programming in 9th grade.

My Algebra I book actually had a PL/I chapter, but we conveniently
skipped over it. That was Fortran IV days, and I found PL/I much
more fun to program in.

There are actual stories from those designing PL/I. Among others,
and I suspect unlike many programming languages, PL/I (or NPL)
was designed before the first compiler was started.

(For those interested, there is what Knuth calls Fortran 0, that is,
the language as it was thought up before the first compiler.)

In any case, when they were first working on PL/I, they thought about
making it more compatible with (the then current) Fortran, but decided
that in the time they had (less than a year) that was not possible.

One result of designing before implementation, is that come features
turned out harder to implement than they might have thought.
(And especially considering the smaller and slower computers
of the time.) Many original PL/I features have now made it into
Fortran, close to 60 years later. It is also interesting to see the
ones that haven't.

For one, PL/I had generic intrinsic functions from the beginning,
and still more generic than Fortran. You can, for example, call
SQRT with an integer (that is, fixed point) argument. Since PL/I
allows fixed point types with the radix point other than just to the
right of the LSD, that makes sense. (In many cases, values are
converted to double precision floating point, and that is used
for the actual function call.) And yet Fortran still doesn't do that.

(PL/I will even let you call SQRT with a CHAR argument, and do
the conversion for you, if the value looks like a number.)

Sometimes it looks to me that when features are added to Fortran,
they try to make it as hard as possible for users to use them.
Complicated rules are added, so that both compiler writers
and programmers have a hard time figuring them out.

It looks to me like PL/I tends to have simpler rules, though
sometimes harder for compiler writers.

But yes, there aren't enough PL/I users to get compilers writers
interested, and not enough compilers to get users interested.







Gary Scott

unread,
Mar 28, 2022, 5:46:07 PM3/28/22
to
Some of those "features" of PL/I do not encourage the most efficient
code. Fortran in some ways forces you to think in ways that encourage
execution efficiency.

gah4

unread,
Mar 28, 2022, 6:32:11 PM3/28/22
to
On Monday, March 28, 2022 at 2:46:07 PM UTC-7, Gary Scott wrote:

(snip)

> Some of those "features" of PL/I do not encourage the most efficient
> code. Fortran in some ways forces you to think in ways that encourage
> execution efficiency.

I suppose so.

Well, I suspect that for any language, there are not so obvious ways to
do things slow, and fast.

A forever favorite for Fortran, at least since the days of virtual memory
and cache, is using arrays in the wrong order.

But often enough, code efficiency is not the first thing you should
be thinking about. Getting the right answer is more important!

OK, one funny thing. Fortran array expressions are defined such that
the whole right hand side is evaluated before the left side is changed.
(Not necessarily the most efficient way.) PL/I defines array expressions
element by element, so if you do:

X = X + X(10);

the changed X(10) is used in later assignments.

Either one could have left it undefined, such that it is up to the user
to avoid the problem. PL/I compilers used to be good at warning you
about temporary arrays that might be needed. More of a problem
for space efficiency than time efficiency, but both can be important.

It is hard to say that either one encourages efficient code, though.

OK, why did Fortran remove allowing real variables in DO loops?
I don't think it is to encourage efficient code. (Note that PL/I
even allows complex and CHAR variables in DO loops.)



Robin Vowels

unread,
Mar 28, 2022, 10:26:33 PM3/28/22
to
On Tuesday, March 29, 2022 at 6:31:15 AM UTC+11, gah4 wrote:
> On Monday, March 28, 2022 at 6:50:52 AM UTC-7, Beliavsky wrote:
>
> (snip)
> > > We have been using these PL/I facilities for 55 years.
> Possibly with a 55 year old compiler.

A number of PL/I compilers are available, including one currently
under development.

> I was doing both Fortran and PL/I programming in 9th grade.
>
> My Algebra I book actually had a PL/I chapter, but we conveniently
> skipped over it. That was Fortran IV days, and I found PL/I much
> more fun to program in.
>
> There are actual stories from those designing PL/I. Among others,
> and I suspect unlike many programming languages, PL/I (or NPL)
> was designed before the first compiler was started.
>
> (For those interested, there is what Knuth calls Fortran 0, that is,
> the language as it was thought up before the first compiler.)
>
> In any case, when they were first working on PL/I, they thought about
> making it more compatible with (the then current) Fortran, but decided
> that in the time they had (less than a year) that was not possible.

That is false. They decided that is was not possible to make FORTRAN VI
(as PL/I was first called) compatible with FORTRAN IV, and that
it was therefore necessary to embark on designing a new language
having substantially better facilities than FORTRAN. This language
would include facilities for both scientific and commercial computations.

> One result of designing before implementation, is that come features
> turned out harder to implement than they might have thought.
> (And especially considering the smaller and slower computers
> of the time.) Many original PL/I features have now made it into
> Fortran, close to 60 years later. It is also interesting to see the
> ones that haven't.
>
> For one, PL/I had generic intrinsic functions from the beginning,
> and still more generic than Fortran. You can, for example, call
> SQRT with an integer (that is, fixed point) argument. Since PL/I
> allows fixed point types with the radix point other than just to the
> right of the LSD, that makes sense. (In many cases, values are
> converted to double precision floating point, and that is used
> for the actual function call.) And yet Fortran still doesn't do that.
>
> (PL/I will even let you call SQRT with a CHAR argument, and do
> the conversion for you, if the value looks like a number.)
>
> Sometimes it looks to me that when features are added to Fortran,
> they try to make it as hard as possible for users to use them.
> Complicated rules are added, so that both compiler writers
> and programmers have a hard time figuring them out.
>
> It looks to me like PL/I tends to have simpler rules, though
> sometimes harder for compiler writers.
>
> But yes, there aren't enough PL/I users to get compilers writers
> interested, and not enough compilers to get users interested.

A PL/I compiler is currently under development, already implementing
most of PL/I.

And of course, IBM is still developing its PL/I compiler.

Robin Vowels

unread,
Mar 28, 2022, 10:27:43 PM3/28/22
to
On Tuesday, March 29, 2022 at 8:46:07 AM UTC+11, Gary Scott wrote:

> Some of those "features" of PL/I do not encourage the most efficient
> code. Fortran in some ways forces you to think in ways that encourage
> execution efficiency.

Such as?

FortranFan

unread,
Mar 28, 2022, 11:55:10 PM3/28/22
to
On Monday, March 28, 2022 at 3:31:15 PM UTC-4, gah4 wrote:
> ..
> But yes, there aren't enough PL/I users to get compilers writers
> interested, and not enough compilers to get users interested.

PL/I appears to many to have tried to be a language "that did everything".

There have been many "imitators" since, they go by C++ and its variants.

Thomas Koenig

unread,
Mar 29, 2022, 1:39:24 AM3/29/22
to
gah4 <ga...@u.washington.edu> schrieb:

> OK, why did Fortran remove allowing real variables in DO loops?
> I don't think it is to encourage efficient code. (Note that PL/I
> even allows complex and CHAR variables in DO loops.)

I don't have a first-hand account of why it happened, but there
is a strong suspect: Rounding errors leading to uncertainties
about the number of iterations.

While there is little doubt about the intended semantics of

DO R = 0.,10.,0.5

there is likely to be problems with

DO R = 0., 10, 0.1

(I'm not 100% convinced about that, since one might
as well write

DO R = 0., 10.05, 0.1

or

DO R=0., 9.95, 0.1

but I suspect that people got it wrong a lot).

fiz...@gmail.com

unread,
Mar 29, 2022, 6:33:56 AM3/29/22
to
On Tuesday, March 29, 2022 at 4:26:33 AM UTC+2, Robin Vowels wrote:
> >
> > But yes, there aren't enough PL/I users to get compilers writers
> > interested, and not enough compilers to get users interested.
> A PL/I compiler is currently under development, already implementing
> most of PL/I.
>
> And of course, IBM is still developing its PL/I compiler.

For Fortran, there are a number of both open and closed source compilers with large user bases and developer communities. That means, that one is almost certain not to have to rewrite anything in a new language just because the old one is not supported any more or not available on a new platform. The IBM one is neither cheap nor widely marketed, and the other one is closed source, developed by a rather small company. Also, there is an alternative complicated language with all the features one might imagine, that has a number of both open and closed source compilers, in addition to a large user base, namely C++.

Gary Scott

unread,
Mar 29, 2022, 10:01:41 AM3/29/22
to
yes...but yuck...

gah4

unread,
Mar 29, 2022, 2:16:51 PM3/29/22
to
Well, yes. But for me, it isn't up to the compiler to force me,
(and in only one specific case) to avoid rounding errors.

So, okay, the language can be designed to encourage efficient code,
but it shouldn't require it.

The actual reason this one bothers me, is that when I was younger
I would sometimes translate BASIC programs to Fortran, from
implementations that only have a floating point type.

Maybe it is too long ago now, but remember that the product
that made Microsoft is a BASIC interpreter. Millions of people
started programming on such systems, where FOR loops only
have a floating point type.

The one case I can imagine where a Fortran user might really
want to use a floating point DO loop is labels for a plot axis.
And really, if one is close enough to run into that, it isn't likely
to be the worst thing that could happen. But good programmers
will add a small amount to be sure.


Ron Shepard

unread,
Mar 30, 2022, 1:28:17 AM3/30/22
to
On 3/29/22 1:16 PM, gah4 wrote:
> On Monday, March 28, 2022 at 10:39:24 PM UTC-7, Thomas Koenig wrote:
>> gah4 <ga...@u.washington.edu> schrieb:
>>> OK, why did Fortran remove allowing real variables in DO loops?
>>> I don't think it is to encourage efficient code. (Note that PL/I
>>> even allows complex and CHAR variables in DO loops.)
>
>> I don't have a first-hand account of why it happened, but there
>> is a strong suspect: Rounding errors leading to uncertainties
>> about the number of iterations.
>
>> While there is little doubt about the intended semantics of
>
>> DO R = 0.,10.,0.5
>
>> there is likely to be problems with
>
>> DO R = 0., 10, 0.1
>
>> (I'm not 100% convinced about that, since one might
>> as well write
>
>> DO R = 0., 10.05, 0.1
>
>> or
>
>> DO R=0., 9.95, 0.1
>
>> but I suspect that people got it wrong a lot).
>
> Well, yes. But for me, it isn't up to the compiler to force me,
> (and in only one specific case) to avoid rounding errors.
>
> So, okay, the language can be designed to encourage efficient code,
> but it shouldn't require it.

It isn't necessarily efficient code in this case, it is code that
doesn't surprise the programmer. I personally was glad to see this
feature dropped.

>
> The actual reason this one bothers me, is that when I was younger
> I would sometimes translate BASIC programs to Fortran, from
> implementations that only have a floating point type.

Yeah, BASIC should not be the model programming language for fortran.

Ok, here is the problem with floating point loops in fortran. I don't
know how BASIC designed their loops, but in fortran, the first thing
that happens is that the trip count is evaluated. That determines the
number of iterations of the loop (excepting early exits, etc.).

Then the loop index is initialized and its value is incremented each
pass through the loop. See the problem now? In floating point
arithmetic, roundoff errors can accumulate for the floating point index
value, so during the final loop iteration, its value can be less than
the upper bound (surprising the programmer who thinks there should have
been additional passes through the loop body), or it can be greater than
the upper bound (surprising the programmer who thinks extra iterations
were performed by mistake.

Except for some exceptional situations where the loop ranges and indexes
occur without rounding error, either one or the other of those two
surprising things happens. In other words, in the typical situation, the
programmer is surprised. That is the sign that this was a poorly
designed feature to begin with. Another sign is that the rounding errors
can change depending on how the rounding mode is set at the time the
loop is executed, or it can change with compiler optimization level,
where the increment is done in different ways or using a different
instruction sequence.

So no matter how you look at it, it was a poor language design choice.
And doing loops with integer counters, which does not suffer from this
kind of roundoff error, is not only easy, sometimes the code is even
simpler and easier to understand. And yes, as you point out, it may be
more efficient too.

$.02 -Ron Shepard

gah4

unread,
Mar 30, 2022, 9:19:47 AM3/30/22
to
On Tuesday, March 29, 2022 at 10:28:17 PM UTC-7, Ron Shepard wrote:
> On 3/29/22 1:16 PM, gah4 wrote:

(snip)
> > The actual reason this one bothers me, is that when I was younger
> > I would sometimes translate BASIC programs to Fortran, from
> > implementations that only have a floating point type.

> Yeah, BASIC should not be the model programming language for fortran.

> Ok, here is the problem with floating point loops in fortran. I don't
> know how BASIC designed their loops, but in fortran, the first thing
> that happens is that the trip count is evaluated. That determines the
> number of iterations of the loop (excepting early exits, etc.).

Yes. But even so, I don't believe that it should be up to compilers
(and language designers) to decide.

And yes that might give different results than the more usual loop and
compare structure.

> Then the loop index is initialized and its value is incremented each
> pass through the loop. See the problem now? In floating point
> arithmetic, roundoff errors can accumulate for the floating point index
> value, so during the final loop iteration, its value can be less than
> the upper bound (surprising the programmer who thinks there should have
> been additional passes through the loop body), or it can be greater than
> the upper bound (surprising the programmer who thinks extra iterations
> were performed by mistake.

There are (maybe a small number of) cases where the programmer
doesn't care. And also, as noted, there the rounding was considered
in advance. In addition, this will mostly go away when decimal floating
point gets more popular.

> Except for some exceptional situations where the loop ranges and indexes
> occur without rounding error, either one or the other of those two
> surprising things happens. In other words, in the typical situation, the
> programmer is surprised. That is the sign that this was a poorly
> designed feature to begin with. Another sign is that the rounding errors
> can change depending on how the rounding mode is set at the time the
> loop is executed, or it can change with compiler optimization level,
> where the increment is done in different ways or using a different
> instruction sequence.

> So no matter how you look at it, it was a poor language design choice.
> And doing loops with integer counters, which does not suffer from this
> kind of roundoff error, is not only easy, sometimes the code is even
> simpler and easier to understand. And yes, as you point out, it may be
> more efficient too.

There are some interesting Java features designed to avoid problems
that C programmers make. One is that scalar variables, including
reference variables, are required to be initialized before use, in a way
that the compiler can verify. There are cases where the compiler
can't verify, though, in which case the usual solution is to just put
an initializer on the declaration. (Which C and Java allow for auto
variables.)

On the other hand, arrays (which are objects) are always zero
(or false) when created. It is too hard for the compiler to verify
that every array element is assigned before use.

Another funny (for C programmers) Java feature is designed to
avoid the common C mistake of writing

if(x=y) ...

when one meant to write

if(x==y) ...

C if statements consider anything non-zero (or non-null pointer) as true,
but Java only allows a boolean expression. So,

if(x=y) ...

is only legal for boolean x and y, which is rare enough.

But both of those are to catch mistakes by programmers, where
they didn't write what they (presumably) meant to write.

I suppose it is possible for someone to accidentally write a REAL DO
loop, but it doesn't seem so likely. And especially unlikely to
for the case of non-integer increment value.

And Fortran still allows you to make all kinds of other rounding
errors, including in IF statements, maybe even in loops!




Robin Vowels

unread,
Mar 30, 2022, 8:52:11 PM3/30/22
to
On Thursday, March 31, 2022 at 12:19:47 AM UTC+11, gah4 wrote:

> And Fortran still allows you to make all kinds of other rounding
> errors, including in IF statements, maybe even in loops!

Silverfrost F95 warns when you compare REALs in an IF statement.

gah4

unread,
Mar 30, 2022, 10:06:54 PM3/30/22
to
I wouldn't be against a warning for DO statements.

By the way:

DCL I FIXED BIN(31,0) COMPLEX;
DO I=1+1I BY 1+1I WHILE(ABS(I)<200);
PUT SKIP LIST(I, I**I,SQRT(I));
END;

Robin Vowels

unread,
Apr 1, 2022, 12:17:26 AM4/1/22
to
On Thursday, March 31, 2022 at 1:06:54 PM UTC+11, gah4 wrote:
> On Wednesday, March 30, 2022 at 5:52:11 PM UTC-7, Robin Vowels wrote:
> > On Thursday, March 31, 2022 at 12:19:47 AM UTC+11, gah4 wrote:
> >
> > > And Fortran still allows you to make all kinds of other rounding
> > > errors, including in IF statements, maybe even in loops!
.
> > Silverfrost F95 warns when you compare REALs in an IF statement.
> I wouldn't be against a warning for DO statements.
>
> By the way:
>
> DCL I FIXED BIN(31,0) COMPLEX;
> DO I=1+1I BY 1+1I WHILE(ABS(I)<200);
> PUT SKIP LIST(I, I**I,SQRT(I));
> END;
.
This would never have run to completion using the PL/I-F compiler,
for floating-point overflow would have occurred at around the 50th
iteration.
.
It won't compile because the BY option cannot be COMPLEX.

gah4

unread,
Apr 1, 2022, 2:53:45 AM4/1/22
to
On Thursday, March 31, 2022 at 9:17:26 PM UTC-7, Robin Vowels wrote:

(snip, I wrote)

> > DCL I FIXED BIN(31,0) COMPLEX;
> > DO I=1+1I BY 1+1I WHILE(ABS(I)<200);
> > PUT SKIP LIST(I, I**I,SQRT(I));
> > END;

> This would never have run to completion using the PL/I-F compiler,
> for floating-point overflow would have occurred at around the 50th
> iteration.

> It won't compile because the BY option cannot be COMPLEX.

I actually didn't try that one, but one I did 45 years ago:

DCL (A, B, C, D) CHAR(20);
B='1';
C='. 100';
D='1';
DO A=B TO C BY D;
PUT SKIP LIST(A, SQRT(A));
END;

So, I don't know if BY can be COMPLEX, but I
do know that it can be CHAR.
(And the sqrt are double precision.)

(How I knew that 45 years ago, I am not sure.)

And the loop test is done as a character comparison, not
a numeric comparison. The blanks in C are important.

And I won't ask when Fortran gets COMPLEX or CHARACTER
DO loops.



Robin Vowels

unread,
Apr 1, 2022, 7:20:55 AM4/1/22
to
On Friday, April 1, 2022 at 5:53:45 PM UTC+11, gah4 wrote:
> On Thursday, March 31, 2022 at 9:17:26 PM UTC-7, Robin Vowels wrote:
>
> (snip, I wrote)
> > > DCL I FIXED BIN(31,0) COMPLEX;
> > > DO I=1+1I BY 1+1I WHILE(ABS(I)<200);
> > > PUT SKIP LIST(I, I**I,SQRT(I));
> > > END;
> > This would never have run to completion using the PL/I-F compiler,
> > for floating-point overflow would have occurred at around the 50th
> > iteration.
> > It won't compile because the BY option cannot be COMPLEX.
.
IBM's PL/I Language Specification manuals C28-6571-1 of 1965
and C28-6571-3 of 1966
give an example of a complex constant as a BY component.
Whether these were actually implemented is not known;
both manuals state that not all these facilities will be implemented
in the first release of the compiler.
If complex BY was available in 1966, your segment would
have compiled and run, subject to the limit mentioned above
of some 50 iterations.
.
However, a complex BY is not available in Windows PL/I.

Robin Vowels

unread,
Apr 4, 2022, 4:31:39 AM4/4/22
to
On Friday, April 1, 2022 at 5:53:45 PM UTC+11, gah4 wrote:
> On Thursday, March 31, 2022 at 9:17:26 PM UTC-7, Robin Vowels wrote:
>
> (snip, I wrote)
> > > DCL I FIXED BIN(31,0) COMPLEX;
> > > DO I=1+1I BY 1+1I WHILE(ABS(I)<200);
> > > PUT SKIP LIST(I, I**I,SQRT(I));
> > > END;
> > This would never have run to completion using the PL/I-F compiler,
> > for floating-point overflow would have occurred at around the 50th
> > iteration.
> > It won't compile because the BY option cannot be COMPLEX.
> I actually didn't try that one, but one I did 45 years ago:
>
> DCL (A, B, C, D) CHAR(20);
> B='1';
> C='. 100';
> D='1';
> DO A=B TO C BY D;
> PUT SKIP LIST(A, SQRT(A));
> END;
.
This one won't work.
Even if the error in the assignment to C were corrected,
it still won't work.
The reason?
Conversion from numeric to character (after the arithmetic)
introduces leading blanks, that causes inequality when
the control variable A is compared with C.
That results in an infinite loop.
For the code to work, the string constants assigned to both B and C must be written
as strings containing exactly 18 characters (right adjusted, of course).

gah4

unread,
Apr 4, 2022, 3:19:29 PM4/4/22
to
On Monday, April 4, 2022 at 1:31:39 AM UTC-7, Robin Vowels wrote:

(snip)
> > I actually didn't try that one, but one I did 45 years ago:

> > DCL (A, B, C, D) CHAR(20);
> > B='1';
> > C='. 100';
> > D='1';
> > DO A=B TO C BY D;
> > PUT SKIP LIST(A, SQRT(A));
> > END;

> This one won't work.
> Even if the error in the assignment to C were corrected,
> it still won't work.
> The reason?
> Conversion from numeric to character (after the arithmetic)
> introduces leading blanks, that causes inequality when
> the control variable A is compared with C.
> That results in an infinite loop.
> For the code to work, the string constants assigned to both B and C must be written
> as strings containing exactly 18 characters (right adjusted, of course).

The period seems to be from my computer believing it is the end of a sentence,
and adding it when I wasn't looking.

As well as I remember from 45 years ago, it needs three blanks before the 100
to match the result of the conversion. That might be different for different systems,
though. But yes, with no blanks it is an infinite loop, and did work 45 years ago.

I also had a:
I = 0;
DO IMAG(I) = 1 TO 100;
PUT SKIP LIST(I, I**I);
END;

loop, which also worked, and the first time I learned that
1I**1I is real, but the other ones are not.

If Fortran allowed real DO loops, then

DO I%IM = 1, 100

(Or if Fortran had something like:

DCL I FIXED BIN(31,0) COMPLEX;

that is, an integer complex data type.




0 new messages