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

end-of-file IOSTAT / debugging

710 views
Skip to first unread message

Dave Tholen

unread,
Jul 15, 2022, 7:47:37 AM7/15/22
to
If you read (sequentially) past the end-of-file, gfortran sets the value
of IOSTAT to -1, but if you read a second time, gfortran sets the value
of IOSTAT to 5001. I discovered this situation after having written a
program expecting subsequent READs to all return a negative number, and
of course the program didn't behave as expected until I investigated the
problem. So I'm curious as to why the choice was made to have IOSTAT
set to something other than -1 on any READ attempt after the end-of-file
condition has been triggered. Isn't the file pointer still just beyond
the last record in the file, even after the first failed READ?



On a completely separate matter, I have a different program that
didn't behave as expected, and that misbehavior was totally repeatable.
In an attempt to debug the program, I added a WRITE statement to check
on the value of a variable during execution. However, once the WRITE
statement was added, the program started behaving properly, repeatably.
Comment out the added WRITE statement, and the program once again
misbehaves, repeatedly. Re-enable the WRITE statement, and everything
is once again hunky-dory. Damned frustrating. It's too easy to blame
the optimizer. Anybody have any generic advice on what to look for in
such a situation?

Robin Vowels

unread,
Jul 15, 2022, 10:45:58 AM7/15/22
to
On Friday, July 15, 2022 at 9:47:37 PM UTC+10, Dave Tholen wrote:
> If you read (sequentially) past the end-of-file, gfortran sets the value
> of IOSTAT to -1, but if you read a second time, gfortran sets the value
> of IOSTAT to 5001. I discovered this situation after having written a
> program expecting subsequent READs to all return a negative number, and
> of course the program didn't behave as expected until I investigated the
> problem. So I'm curious as to why the choice was made to have IOSTAT
> set to something other than -1 on any READ attempt after the end-of-file
> condition has been triggered. Isn't the file pointer still just beyond
> the last record in the file, even after the first failed READ?

You are expected to test for IOSTAT and deal with the end-of-file condition.
You are not expected to continue reading the file.
>
>
> On a completely separate matter, I have a different program that
> didn't behave as expected, and that misbehavior was totally repeatable.
> In an attempt to debug the program, I added a WRITE statement to check
> on the value of a variable during execution. However, once the WRITE
> statement was added, the program started behaving properly, repeatably.

That suggests that there is a bug in your program. Possibly something has
been overwritten.
Turn on subscript bounds checking (if available).
And while you're at it, turn on all checks.

steve kargl

unread,
Jul 15, 2022, 1:48:33 PM7/15/22
to
Dave Tholen wrote:

> If you read (sequentially) past the end-of-file, gfortran sets the value
> of IOSTAT to -1, but if you read a second time, gfortran sets the value
> of IOSTAT to 5001. I discovered this situation after having written a
> program expecting subsequent READs to all return a negative number, and
> of course the program didn't behave as expected until I investigated the
> problem. So I'm curious as to why the choice was made to have IOSTAT
> set to something other than -1 on any READ attempt after the end-of-file
> condition has been triggered. Isn't the file pointer still just beyond
> the last record in the file, even after the first failed READ?

What version of the compiler and operating system?

What does IOMSG tell you? Likely, you have hit two different errors.

> On a completely separate matter, I have a different program that
> didn't behave as expected, and that misbehavior was totally repeatable.
> In an attempt to debug the program, I added a WRITE statement to check
> on the value of a variable during execution. However, once the WRITE
> statement was added, the program started behaving properly, repeatably.
> Comment out the added WRITE statement, and the program once again
> misbehaves, repeatedly. Re-enable the WRITE statement, and everything
> is once again hunky-dory. Damned frustrating. It's too easy to blame
> the optimizer. Anybody have any generic advice on what to look for in
> such a situation?

Remove the write statement and compile with -Wall -fcheck=all. This
might find where you are stomping on memory.

--
steve

gah4

unread,
Jul 15, 2022, 4:20:07 PM7/15/22
to
On Friday, July 15, 2022 at 4:47:37 AM UTC-7, Dave Tholen wrote:
> If you read (sequentially) past the end-of-file, gfortran sets the value
> of IOSTAT to -1, but if you read a second time, gfortran sets the value
> of IOSTAT to 5001. I discovered this situation after having written a
> program expecting subsequent READs to all return a negative number, and
> of course the program didn't behave as expected until I investigated the
> problem. So I'm curious as to why the choice was made to have IOSTAT
> set to something other than -1 on any READ attempt after the end-of-file
> condition has been triggered. Isn't the file pointer still just beyond
> the last record in the file, even after the first failed READ?

I haven't thought about this in a lot of years, but in the days of
magnetic tapes, some systems allowed one to read the EOF,
and then go on to the next file on the tape.

Though Fortran 66 has no method for detecting EOF, you are just
supposed to stop reading before it happens.

I believe for tapes in Unix, when you get to the end, the system
call return 0 bytes, as the sign of the EOF, and then you go onto
the next file. (That is, past the tape mark.)

Disk files don't do that, though.



Steve Lionel

unread,
Jul 15, 2022, 4:33:31 PM7/15/22
to
On Fri, 15 Jul 2022 07:45:56 -0700, Robin Vowels wrote:

> You are expected to test for IOSTAT and deal with the end-of-file
> condition.
> You are not expected to continue reading the file.

MIL-STD-1753 specified that you could, when reading magnetic tape (see
https://stevelionel.com/drfortran/2020/05/16/doctor-fortran-in-military-
strength/).

The Fortran standard says (12.11.1), that when an "endfile record is
encountered during the reading of a file connected for sequential access",
"if the file specified in the input statement is an external record file,
it is positioned after the endfile record;" (12.11.3). What happens after
that is not specified, though you are allowed to BACKSPACE over the
endfile record. Note that there doesn't need to be any physical
representation of an endfile record.

gfortran is within its rights to give you a different IOSTAT value in this
case, and I could make an argument that -1 is NOT the correct thing to
return here. I tried ifort and nagfor - ifort returns -1 on the read past
the EOF, nagfor uses 210, corresponding to "READ/WRITE attempted after
ENDFILE on unit 1". (I can't get too worked up over ifort returning -1,
however...)


--
Steve Lionel
ISO/IEC JTC1/SC22/WG5 (Fortran) Convenor
Retired Intel Fortran developer/support
Email: firstname at firstnamelastname dot com
Twitter: @DoctorFortran
LinkedIn: https://www.linkedin.com/in/stevelionel
Blog: https://stevelionel.com/drfortran
WG5: https://wg5-fortran.org

Dave Tholen

unread,
Jul 15, 2022, 9:30:41 PM7/15/22
to
>> If you read (sequentially) past the end-of-file, gfortran sets the value
>> of IOSTAT to -1, but if you read a second time, gfortran sets the value
>> of IOSTAT to 5001. I discovered this situation after having written a
>> program expecting subsequent READs to all return a negative number, and
>> of course the program didn't behave as expected until I investigated the
>> problem. So I'm curious as to why the choice was made to have IOSTAT
>> set to something other than -1 on any READ attempt after the end-of-file
>> condition has been triggered. Isn't the file pointer still just beyond
>> the last record in the file, even after the first failed READ?

> You are expected to test for IOSTAT and deal with the end-of-file condition.
> You are not expected to continue reading the file.

I actually do test for IOSTAT and deal with the end-of-file condition by
exiting the DO loop with the READ statement. But once the DO loop has
been exited, the program is in an outer DO loop, which can also read the
file. It also tests IOSTAT to deal with the end-of-file condition, but
it tested for a negative number, which IOSTAT was no longer set to.

And if you must know why the nested DO loops, one loop dealt with data
while the other loop dealt with metadata. It was easily fixable. My
question here was not about how to fix the problem, but rather to find
out the rationale for changing the value of IOSTAT in such a situation.
My expectation was that IOSTAT would remain negative. My expectation
was wrong, hence the curiosity.

>> On a completely separate matter, I have a different program that
>> didn't behave as expected, and that misbehavior was totally repeatable.
>> In an attempt to debug the program, I added a WRITE statement to check
>> on the value of a variable during execution. However, once the WRITE
>> statement was added, the program started behaving properly, repeatably.

> That suggests that there is a bug in your program.

Brilliant.

> Possibly something has
> been overwritten.

I already thought about that, hence the WRITE statement to examine
the values of the array indices. The values were within range and
the program worked properly with the WRITE statement enabled. Comment
out the WRITE statement, and the misbehavior returned. Hence the
frustration.

> Turn on subscript bounds checking (if available).
> And while you're at it, turn on all checks.

Easier said than done, as the program was built from dozens of separately
written and compiled subprograms. It has not always been obvious to me
whether a compilation flag needs to be applied to every single subprogram
in order to accomplish a goal.

Dave Tholen

unread,
Jul 15, 2022, 9:46:40 PM7/15/22
to
>> If you read (sequentially) past the end-of-file, gfortran sets the value
>> of IOSTAT to -1, but if you read a second time, gfortran sets the value
>> of IOSTAT to 5001. I discovered this situation after having written a
>> program expecting subsequent READs to all return a negative number, and
>> of course the program didn't behave as expected until I investigated the
>> problem. So I'm curious as to why the choice was made to have IOSTAT
>> set to something other than -1 on any READ attempt after the end-of-file
>> condition has been triggered. Isn't the file pointer still just beyond
>> the last record in the file, even after the first failed READ?

> What version of the compiler and operating system?

Unfortunately, I'm not sitting in front of the computer in question at
the moment, but I am sitting in front of a different computer that was
purchased at the same time and loaded with the same software, so there's
a good chance it's gfortran 7.1.0. The operating system is Windows 10 Pro
version 21H2. I'm expecting Windows Update to reboot the system any day
now to install the July patches (as happened last night to the system
I'm using at the moment).

> What does IOMSG tell you?

I'm unfamiliar with IOMSG. Sounds like an intrinsic that returns a
text description of an IOSTAT numerical value, but I don't see it listed
among the intrinsic procedures for gfortran. Could you elaborate?

> Likely, you have hit two different errors.

Yeah, the first being end-of-file and the second being past-end-of-file.
As I noted in an earlier response, my expectation was that both would
return negative numbers, but that expectation was wrong, at least for
gfortran. I would have been just fine with ifort, thanks to Steve
Lionel's test.

>> On a completely separate matter, I have a different program that
>> didn't behave as expected, and that misbehavior was totally repeatable.
>> In an attempt to debug the program, I added a WRITE statement to check
>> on the value of a variable during execution. However, once the WRITE
>> statement was added, the program started behaving properly, repeatably.
>> Comment out the added WRITE statement, and the program once again
>> misbehaves, repeatedly. Re-enable the WRITE statement, and everything
>> is once again hunky-dory. Damned frustrating. It's too easy to blame
>> the optimizer. Anybody have any generic advice on what to look for in
>> such a situation?

> Remove the write statement and compile with -Wall -fcheck=all. This
> might find where you are stomping on memory.

I'll give that a try over the weekend.


gah4

unread,
Jul 15, 2022, 10:04:18 PM7/15/22
to
On Friday, July 15, 2022 at 4:47:37 AM UTC-7, Dave Tholen wrote:
> If you read (sequentially) past the end-of-file, gfortran sets the value
> of IOSTAT to -1, but if you read a second time, gfortran sets the value
> of IOSTAT to 5001. I discovered this situation after having written a
> program expecting subsequent READs to all return a negative number, and
> of course the program didn't behave as expected until I investigated the
> problem. So I'm curious as to why the choice was made to have IOSTAT
> set to something other than -1 on any READ attempt after the end-of-file
> condition has been triggered. Isn't the file pointer still just beyond
> the last record in the file, even after the first failed READ?

If I understand it right, you should test for not zero, and act accordingly.

It is negative for EOF, but positive for I/O errors, which most likely you
should also exit your loop, and/or handle appropriately.

Otherwise, it makes some sense. In the first case, there is actual EOF.
In the second, reading after EOF, is an I/O error, and so reported.

Unless you plan to test for and take appropriate action for different
I/O errors, taking action for any non-zero value makes sense.

I believe this is a not unusual error in some other languages,
which I won't mention.






jfh

unread,
Jul 15, 2022, 11:11:54 PM7/15/22
to
In an open, inquire, read or write statement you may include iomsg=msg as well as iostat=ios if you have a scalar variable of type character that's long enough for the error messge, and you write msg if ios was nonzero. The length of msg will depend on what compiler you used, what ios was, and how long the name of the offending file was. Iomsg and iostat are not intrinsics but specifiers in those 4 kinds of statement.

Robin Vowels

unread,
Jul 16, 2022, 3:33:31 AM7/16/22
to
On Saturday, July 16, 2022 at 6:33:31 AM UTC+10, Steve Lionel wrote:
> On Fri, 15 Jul 2022 07:45:56 -0700, Robin Vowels wrote:
>
> > You are expected to test for IOSTAT and deal with the end-of-file
> > condition.
> > You are not expected to continue reading the file.
> MIL-STD-1753 specified that you could, when reading magnetic tape
.
That's irrelevant.

Robin Vowels

unread,
Jul 16, 2022, 3:51:18 AM7/16/22
to
On Saturday, July 16, 2022 at 11:30:41 AM UTC+10, Dave Tholen wrote:
> >> If you read (sequentially) past the end-of-file, gfortran sets the value
> >> of IOSTAT to -1, but if you read a second time, gfortran sets the value
> >> of IOSTAT to 5001. I discovered this situation after having written a
> >> program expecting subsequent READs to all return a negative number, and
> >> of course the program didn't behave as expected until I investigated the
> >> problem. So I'm curious as to why the choice was made to have IOSTAT
> >> set to something other than -1 on any READ attempt after the end-of-file
> >> condition has been triggered. Isn't the file pointer still just beyond
> >> the last record in the file, even after the first failed READ?
>
> > You are expected to test for IOSTAT and deal with the end-of-file condition.
> > You are not expected to continue reading the file.
.
> I actually do test for IOSTAT and deal with the end-of-file condition by
> exiting the DO loop with the READ statement. But once the DO loop has
> been exited, the program is in an outer DO loop, which can also read the
> file.
.
You need to fix the logic.
.
> It also tests IOSTAT to deal with the end-of-file condition,
.
The program has already hit the end of file.
Now you are trying to read read the same file at the same place.
.
> but
> it tested for a negative number, which IOSTAT was no longer set to.
.
You need to avoid reading after end of file has been detected.
.
> And if you must know why the nested DO loops, one loop dealt with data
> while the other loop dealt with metadata. It was easily fixable. My
> question here was not about how to fix the problem, but rather to find
> out the rationale for changing the value of IOSTAT in such a situation.
> My expectation was that IOSTAT would remain negative. My expectation
> was wrong, hence the curiosity.
> >> On a completely separate matter, I have a different program that
> >> didn't behave as expected, and that misbehavior was totally repeatable.
> >> In an attempt to debug the program, I added a WRITE statement to check
> >> on the value of a variable during execution. However, once the WRITE
> >> statement was added, the program started behaving properly, repeatably.
>
> > That suggests that there is a bug in your program.
> Brilliant.
> > Possibly something has
> > been overwritten.
> I already thought about that, hence the WRITE statement to examine
> the values of the array indices.
.
In every program unit, subroutine and function in the entire program?
.
> The values were within range and
> the program worked properly with the WRITE statement enabled. Comment
> out the WRITE statement, and the misbehavior returned. Hence the
> frustration.
> > Turn on subscript bounds checking (if available).
> > And while you're at it, turn on all checks.
.
> Easier said than done, as the program was built from dozens of separately
> written and compiled subprograms. It has not always been obvious to me
> whether a compilation flag needs to be applied to every single subprogram
> in order to accomplish a goal.
.
Obviously, program checking needs to be specified for every separate compilation,
as the apparent overwriting could be in any one or more subroutine and function.
Message has been deleted

Robin Vowels

unread,
Jul 16, 2022, 4:39:46 AM7/16/22
to
On Saturday, July 16, 2022 at 6:20:07 AM UTC+10, gah4 wrote:
> On Friday, July 15, 2022 at 4:47:37 AM UTC-7, Dave Tholen wrote:
> > If you read (sequentially) past the end-of-file, gfortran sets the value
> > of IOSTAT to -1, but if you read a second time, gfortran sets the value
> > of IOSTAT to 5001. I discovered this situation after having written a
> > program expecting subsequent READs to all return a negative number, and
> > of course the program didn't behave as expected until I investigated the
> > problem. So I'm curious as to why the choice was made to have IOSTAT
> > set to something other than -1 on any READ attempt after the end-of-file
> > condition has been triggered. Isn't the file pointer still just beyond
> > the last record in the file, even after the first failed READ?
> I haven't thought about this in a lot of years, but in the days of
> magnetic tapes, some systems allowed one to read the EOF,
> and then go on to the next file on the tape.
>
> Though Fortran 66 has no method for detecting EOF, you are just
> supposed to stop reading before it happens.
.
IBM FORTRAN IV of 1966 had EOF= and ERR= options
for the READ statement.
.
PL/I (F) of 1966 raised the ENDFILE condition on attempting to
read after the final data item in the file.

Louis Krupp

unread,
Jul 16, 2022, 5:17:51 AM7/16/22
to
On 7/15/2022 11:48 AM, steve kargl wrote:
> Dave Tholen wrote:
<snip>
>> On a completely separate matter, I have a different program that
>> didn't behave as expected, and that misbehavior was totally repeatable.
>> In an attempt to debug the program, I added a WRITE statement to check
>> on the value of a variable during execution. However, once the WRITE
>> statement was added, the program started behaving properly, repeatably.
>> Comment out the added WRITE statement, and the program once again
>> misbehaves, repeatedly. Re-enable the WRITE statement, and everything
>> is once again hunky-dory. Damned frustrating. It's too easy to blame
>> the optimizer. Anybody have any generic advice on what to look for in
>> such a situation?
> Remove the write statement and compile with -Wall -fcheck=all. This
> might find where you are stomping on memory.
>

I would add -Werror. If you always compile without warnings, your life
will be simpler.

If the presumably unlikely event that you're not already using IMPLICIT
NONE in every program unit, I would do that, too.

Among the other things mentioned, a WRITE statement might mask problems
caused by a variable that's not assigned a value before it's used.

If all else fails, the debugger is your friend. If you haven't
experienced the thrill of stepping through assembler instructions
finding where your wayward variable is stored and examining its value
and figuring out how it got to be what it is, this could be your chance.

Louis

Dave Tholen

unread,
Jul 16, 2022, 6:59:00 AM7/16/22
to
>>>> If you read (sequentially) past the end-of-file, gfortran sets the value
>>>> of IOSTAT to -1, but if you read a second time, gfortran sets the value
>>>> of IOSTAT to 5001. I discovered this situation after having written a
>>>> program expecting subsequent READs to all return a negative number, and
>>>> of course the program didn't behave as expected until I investigated the
>>>> problem. So I'm curious as to why the choice was made to have IOSTAT
>>>> set to something other than -1 on any READ attempt after the end-of-file
>>>> condition has been triggered. Isn't the file pointer still just beyond
>>>> the last record in the file, even after the first failed READ?

>>> You are expected to test for IOSTAT and deal with the end-of-file condition.
>>> You are not expected to continue reading the file.

>> I actually do test for IOSTAT and deal with the end-of-file condition by
>> exiting the DO loop with the READ statement. But once the DO loop has
>> been exited, the program is in an outer DO loop, which can also read the
>> file.

> You need to fix the logic.

Apparently I haven't been clear. The program has already been fixed.
It was fixed before I even posted on this forum. The question is not
how to fix the problem. The question is why the value of IOSTAT was
changed. There must be some rationale.

>> It also tests IOSTAT to deal with the end-of-file condition,

> The program has already hit the end of file.
> Now you are trying to read read the same file at the same place.

That's just it: same file, same place, same action, yet a different
IOSTAT result. Not what I had expected.

>> but
>> it tested for a negative number, which IOSTAT was no longer set to.

> You need to avoid reading after end of file has been detected.

Why? IOSTAT was added so that a program could handle error conditions.
My program was designed to deal with the error condition. Had gfortran
consistently returned a negative IOSTAT for every attempt to READ past
the end-of-file, my program would have worked exactly as intended. Had
I used ifort, my program would have worked exactly as intended.

>> And if you must know why the nested DO loops, one loop dealt with data
>> while the other loop dealt with metadata. It was easily fixable. My
>> question here was not about how to fix the problem, but rather to find
>> out the rationale for changing the value of IOSTAT in such a situation.
>> My expectation was that IOSTAT would remain negative. My expectation
>> was wrong, hence the curiosity.

>>>> On a completely separate matter, I have a different program that
>>>> didn't behave as expected, and that misbehavior was totally repeatable.
>>>> In an attempt to debug the program, I added a WRITE statement to check
>>>> on the value of a variable during execution. However, once the WRITE
>>>> statement was added, the program started behaving properly, repeatably.

>>> That suggests that there is a bug in your program.

>> Brilliant.

>>> Possibly something has
>>> been overwritten.

>> I already thought about that, hence the WRITE statement to examine
>> the values of the array indices.

> In every program unit, subroutine and function in the entire program?

I usually sprinkle WRITE statements around to isolate where the crash
is happening. As I narrow things down, unnecessary WRITE statements are
either removed or commented out. In this particular case, I got it down
to a single WRITE statement that could trigger proper behavior.

>> The values were within range and
>> the program worked properly with the WRITE statement enabled. Comment
>> out the WRITE statement, and the misbehavior returned. Hence the
>> frustration.

>>> Turn on subscript bounds checking (if available).
>>> And while you're at it, turn on all checks.
.
>> Easier said than done, as the program was built from dozens of separately
>> written and compiled subprograms. It has not always been obvious to me
>> whether a compilation flag needs to be applied to every single subprogram
>> in order to accomplish a goal.

> Obviously, program checking needs to be specified for every separate compilation,
> as the apparent overwriting could be in any one or more subroutine and function.

So, you're saying that if my program has subprograms A, B, C, D, and E,
and the crash occurs while it's executing subprogram C, the apparent
overwriting could be in A, B, D, or E?

Dave Tholen

unread,
Jul 16, 2022, 7:01:08 AM7/16/22
to
>> You are expected to test for IOSTAT and deal with the end-of-file
>> condition.
>> You are not expected to continue reading the file.
>
> MIL-STD-1753 specified that you could, when reading magnetic tape (see
> https://stevelionel.com/drfortran/2020/05/16/doctor-fortran-in-military-
> strength/).
>
> The Fortran standard says (12.11.1), that when an "endfile record is
> encountered during the reading of a file connected for sequential access",
> "if the file specified in the input statement is an external record file,
> it is positioned after the endfile record;" (12.11.3). What happens after
> that is not specified, though you are allowed to BACKSPACE over the
> endfile record. Note that there doesn't need to be any physical
> representation of an endfile record.
>
> gfortran is within its rights to give you a different IOSTAT value in this
> case, and I could make an argument that -1 is NOT the correct thing to
> return here.

That argument you could make is precisely what I was hoping to get out of
this thread.

Dave Tholen

unread,
Jul 16, 2022, 7:41:04 AM7/16/22
to
>> If you read (sequentially) past the end-of-file, gfortran sets the value
>> of IOSTAT to -1, but if you read a second time, gfortran sets the value
>> of IOSTAT to 5001. I discovered this situation after having written a
>> program expecting subsequent READs to all return a negative number, and
>> of course the program didn't behave as expected until I investigated the
>> problem. So I'm curious as to why the choice was made to have IOSTAT
>> set to something other than -1 on any READ attempt after the end-of-file
>> condition has been triggered. Isn't the file pointer still just beyond
>> the last record in the file, even after the first failed READ?

> If I understand it right, you should test for not zero, and act accordingly.
>
> It is negative for EOF, but positive for I/O errors, which most likely you
> should also exit your loop, and/or handle appropriately.

Not in this particular case. In older versions of the data file I'm
processing, they used csv format to present dozens and dozens of
quantities for each object in the database, and when a value wasn't
available, they simply omitted it, leading to consecutive commas,
and gfortran's list-directed READ statement handled it splendidly.
However, in the latest version of the data file, a missing value is
now represented as "null". For example, five values might be in
this file as:

18,97.43,null,-4.31,102

but attempting to read the characters "null" into an INTEGER or REAL
variable triggers an I/O error. I do NOT want to exit the READ loop.
However, once the end-of-file is reached, I do want to exit the READ
loop.

> Otherwise, it makes some sense. In the first case, there is actual EOF.
> In the second, reading after EOF, is an I/O error, and so reported.

So, prior to the READ that triggers the end-of-file condition, the
file pointer is after the last record of the file, but before the EOF,
and after the READ that triggers the end-of-file condition, the file
pointer is now after some imaginary EOF? There is no physical EOF
associated with the file. Does the compiler give the file a logical
EOF marker and is able to position the file pointer before and after it?

> Unless you plan to test for and take appropriate action for different
> I/O errors, taking action for any non-zero value makes sense.

I've written numerous programs where different actions are taken for
different I/O errors. A hypothetical (and trivial) example: A
program that converts Fahrenheit to Celsius. DO loop with WRITE
statement that prompts the user to enter a temperature in Fahrenheit
and a READ statement that accepts the user's input. Type in "abc"
and rather than crashing or exiting the loop, the program can say
"try again" and wait for another entry. But enter a CTRL-Z (an
EOF on Windows), and the loop can exit gracefully.

Steve Lionel

unread,
Jul 16, 2022, 10:15:12 AM7/16/22
to
On Fri, 15 Jul 2022 15:46:36 -1000, Dave Tholen wrote:

> I'm unfamiliar with IOMSG. Sounds like an intrinsic that returns a text
> description of an IOSTAT numerical value, but I don't see it listed
> among the intrinsic procedures for gfortran. Could you elaborate?

It's not an intrinsic, it's another keyword for the I/O statement, like
IOSTAT. It was new in Fortran 2018.


--
Steve Lionel
Email: firstname at firstnamelastname dot com
Twitter: @DoctorFortran
Blog: https://stevelionel.com/drfortran

FortranFan

unread,
Jul 16, 2022, 11:10:17 AM7/16/22
to
On Saturday, July 16, 2022 at 10:15:12 AM UTC-4, Steve Lionel wrote:

> On Fri, 15 Jul 2022 15:46:36 -1000, Dave Tholen wrote:
>
> > I'm unfamiliar with IOMSG. Sounds like an intrinsic that returns a text
> > description of an IOSTAT numerical value, but I don't see it listed
> > among the intrinsic procedures for gfortran. Could you elaborate?
> It's not an intrinsic, it's another keyword for the I/O statement, like
> IOSTAT. It was new in Fortran 2018.
>

You must mean Fortran 2003 standard revision given it is the data transfer (READ) statement being discussed here?

Fortran 2018 introduced an optional argument `ERRMSG` to fetch the messages involving intrinsics that interact with the processor environment, correct? Such as get_command, get_environment_variable, etc.

Gary Scott

unread,
Jul 16, 2022, 12:51:51 PM7/16/22
to
I know of at least one operating system that included the concept of EOT
within disk files as well. So you could have multiple files in the same
"disk area". You got and EOF return at end of the current file and if
you read again and there wasn't another file present, you got an EOT
return value. It was convenient for some things.

gah4

unread,
Jul 16, 2022, 1:40:55 PM7/16/22
to
On Saturday, July 16, 2022 at 4:41:04 AM UTC-7, Dave Tholen wrote:

(snip, I wrote)
> > If I understand it right, you should test for not zero, and act accordingly.

> > It is negative for EOF, but positive for I/O errors, which most likely you
> > should also exit your loop, and/or handle appropriately.

> Not in this particular case. In older versions of the data file I'm
> processing, they used csv format to present dozens and dozens of
> quantities for each object in the database, and when a value wasn't
> available, they simply omitted it, leading to consecutive commas,
> and gfortran's list-directed READ statement handled it splendidly.
> However, in the latest version of the data file, a missing value is
> now represented as "null". For example, five values might be in
> this file as:

> 18,97.43,null,-4.31,102

> but attempting to read the characters "null" into an INTEGER or REAL
> variable triggers an I/O error. I do NOT want to exit the READ loop.
> However, once the end-of-file is reached, I do want to exit the READ
> loop.

On either EOF or I/O error, there is no guarantee as to what
is actually stored, or where the file is positioned.

> > Otherwise, it makes some sense. In the first case, there is actual EOF.
> > In the second, reading after EOF, is an I/O error, and so reported.

> So, prior to the READ that triggers the end-of-file condition, the
> file pointer is after the last record of the file, but before the EOF,
> and after the READ that triggers the end-of-file condition, the file
> pointer is now after some imaginary EOF? There is no physical EOF
> associated with the file. Does the compiler give the file a logical
> EOF marker and is able to position the file pointer before and after it?

The standard does have some discussion on that imaginary
EOF record, while indicating that it might not be an actual
physical anything. I am not sure if some historical system
had a physical EOF record that the standard emulates.

In any case, EOF is not an error, and so actual error is different.

> > Unless you plan to test for and take appropriate action for different
> > I/O errors, taking action for any non-zero value makes sense.

> I've written numerous programs where different actions are taken for
> different I/O errors. A hypothetical (and trivial) example: A
> program that converts Fahrenheit to Celsius. DO loop with WRITE
> statement that prompts the user to enter a temperature in Fahrenheit
> and a READ statement that accepts the user's input. Type in "abc"
> and rather than crashing or exiting the loop, the program can say
> "try again" and wait for another entry. But enter a CTRL-Z (an
> EOF on Windows), and the loop can exit gracefully.

I suppose you can do that, I am not sure that there is any
standard behavior, especially as to file position.

Reminds me, Unix, and at least Unix C compilers, all for one
to keep reading after EOF, such that tail -f works. That is,
if the file increases in length then the EOF goes away,
and you can keep reading. I do remember years ago
finding that C in OS/2 allowed that.


Robin Vowels

unread,
Jul 16, 2022, 1:51:01 PM7/16/22
to
On Saturday, July 16, 2022 at 8:59:00 PM UTC+10, Dave Tholen wrote:
> >>>> If you read (sequentially) past the end-of-file, gfortran sets the value
> >>>> of IOSTAT to -1, but if you read a second time, gfortran sets the value
> >>>> of IOSTAT to 5001. I discovered this situation after having written a
> >>>> program expecting subsequent READs to all return a negative number, and
> >>>> of course the program didn't behave as expected until I investigated the
> >>>> problem. So I'm curious as to why the choice was made to have IOSTAT
> >>>> set to something other than -1 on any READ attempt after the end-of-file
> >>>> condition has been triggered. Isn't the file pointer still just beyond
> >>>> the last record in the file, even after the first failed READ?
>
> >>> You are expected to test for IOSTAT and deal with the end-of-file condition.
> >>> You are not expected to continue reading the file.
> >> I actually do test for IOSTAT and deal with the end-of-file condition by
> >> exiting the DO loop with the READ statement. But once the DO loop has
> >> been exited, the program is in an outer DO loop, which can also read the
> >> file.
.
> > You need to fix the logic.
.
> Apparently I haven't been clear.
> The program has already been fixed.
.
But it hasn't been fixed. You admitted it.
You said that after detecting end of file using IOSTAT, you exited the loop,
and the outer loop then proceeded to execute READs on the same file.
.
> It was fixed before I even posted on this forum. The question is not
> how to fix the problem. The question is why the value of IOSTAT was
> changed.
.
That has already been explained to you.
.
> There must be some rationale.
> >> It also tests IOSTAT to deal with the end-of-file condition,
> > The program has already hit the end of file.
> > Now you are trying to read read the same file at the same place.
> That's just it: same file, same place, same action, yet a different
> IOSTAT result. Not what I had expected.
.
Again, that has been explained to you.
.
> >> but
> >> it tested for a negative number, which IOSTAT was no longer set to.
> > You need to avoid reading after end of file has been detected.
> Why? IOSTAT was added so that a program could handle error conditions.
.
Provided that you deal with the condition and do not do silly things like reading
the same file again, after detecting end-of file.
.
> My program was designed to deal with the error condition. Had gfortran
> consistently returned a negative IOSTAT for every attempt to READ past
> the end-of-file, my program would have worked exactly as intended.

Listen up. Your program is in error. Fix it.
.
> Had I used ifort, my program would have worked exactly as intended.
> >> And if you must know why the nested DO loops, one loop dealt with data
> >> while the other loop dealt with metadata. It was easily fixable. My
> >> question here was not about how to fix the problem, but rather to find
> >> out the rationale for changing the value of IOSTAT in such a situation.
> >> My expectation was that IOSTAT would remain negative. My expectation
> >> was wrong, hence the curiosity.
>
> >>>> On a completely separate matter, I have a different program that
> >>>> didn't behave as expected, and that misbehavior was totally repeatable.
> >>>> In an attempt to debug the program, I added a WRITE statement to check
> >>>> on the value of a variable during execution. However, once the WRITE
> >>>> statement was added, the program started behaving properly, repeatably.
>
> >>> That suggests that there is a bug in your program.
>
> >> Brilliant.
>
> >>> Possibly something has
> >>> been overwritten.
>
> >> I already thought about that, hence the WRITE statement to examine
> >> the values of the array indices.
> > In every program unit, subroutine and function in the entire program?
> I usually sprinkle WRITE statements around to isolate where the crash
> is happening. As I narrow things down, unnecessary WRITE statements are
> either removed or commented out. In this particular case, I got it down
> to a single WRITE statement that could trigger proper behavior.
.
You program has errors. Find them with the help of debug options
such as subscript bound errors, substring errors, and the like.

Robin Vowels

unread,
Jul 16, 2022, 1:54:16 PM7/16/22
to
.
The error could be in any of A, B, C, D, E, and/or the main program.

Robin Vowels

unread,
Jul 16, 2022, 2:04:58 PM7/16/22
to
On Sunday, July 17, 2022 at 3:40:55 AM UTC+10, gah4 wrote:
> On Saturday, July 16, 2022 at 4:41:04 AM UTC-7, Dave Tholen wrote:
>
> (snip, I wrote)
> > > If I understand it right, you should test for not zero, and act accordingly.
>
> > > It is negative for EOF, but positive for I/O errors, which most likely you
> > > should also exit your loop, and/or handle appropriately.
>
> > Not in this particular case. In older versions of the data file I'm
> > processing, they used csv format to present dozens and dozens of
> > quantities for each object in the database, and when a value wasn't
> > available, they simply omitted it, leading to consecutive commas,
> > and gfortran's list-directed READ statement handled it splendidly.
> > However, in the latest version of the data file, a missing value is
> > now represented as "null". For example, five values might be in
> > this file as:
>
> > 18,97.43,null,-4.31,102
>
> > but attempting to read the characters "null" into an INTEGER or REAL
> > variable triggers an I/O error.
.
Characters are characters, and cannot be read into an integer or real variable.
An appropriate variable would be a CHARACTER variable, but then the
characters NULL would need to be enclosed in apostrophes.
A better approach might be to read the entire line into a CHARACTER variable,
and then to scan it for 'null, and then to delete the word. Finally read the
altered line.

Louis Krupp

unread,
Jul 16, 2022, 3:23:24 PM7/16/22
to
If each READ statement is definitely reading one and only one line, then
reading each line into a character variable, deleting each instance of
the word 'null', and then reading data from the character variable seems
like the easiest solution by far.

Louis

gah4

unread,
Jul 16, 2022, 8:24:12 PM7/16/22
to
On Saturday, July 16, 2022 at 12:23:24 PM UTC-7, Louis Krupp wrote:

(snip)

> If each READ statement is definitely reading one and only one line, then
> reading each line into a character variable, deleting each instance of
> the word 'null', and then reading data from the character variable seems
> like the easiest solution by far.

I would find it easy enough to preprocess the file, such as:

sed "s/null//" < infile > outfile

Or maybe the generating program has an option to change this.

But yes, as a Fortran solution, reading line by line and processing the
line is often fine, too.

Many years ago (Fortran 77 days), I was reading a file something like:

READ(5,*, END=999) (X(I), Y(I), I=1,999)

and expecting the data to be read, and I to be 1 more than the pairs read.
That was before I saw a copy of the standard, and only had the DEC manuals.

I even had the DEC bug report form, before learning that the standard,
and especially the DEC compilers, didn't require that.

In the case of either EOF or I/O error, what is actually stored, or the value
of implied-DO variables, is undefined.

For my problem, a normal (not implied) DO fixed it, but others are
not so easy to fix.

Ron Shepard

unread,
Jul 17, 2022, 1:54:28 AM7/17/22
to
On 7/16/22 1:04 PM, Robin Vowels wrote:
> Characters are characters, and cannot be read into an integer or real variable.

A machine-specific exception to this was list-directed i/o in VAX
fortran. It would read a T into an integer and translate it to -1, and
it would read a F into an integer and translate it to 0. These were the
internal bit representations for .true. and .false., so it was really
translating between logicals and integers, rather than between
characters and integers.

What do most compilers do when reading the characters NaN or Inf into a
real variable? Do they generate an error, or do they insert the IEEE bit
patterns?

$.02 -Ron Shepard

Dave Tholen

unread,
Jul 17, 2022, 6:13:50 AM7/17/22
to
>>> On a completely separate matter, I have a different program that
>>> didn't behave as expected, and that misbehavior was totally repeatable.
>>> In an attempt to debug the program, I added a WRITE statement to check
>>> on the value of a variable during execution.  However, once the WRITE
>>> statement was added, the program started behaving properly, repeatably.
>>> Comment out the added WRITE statement, and the program once again
>>> misbehaves, repeatedly.  Re-enable the WRITE statement, and everything
>>> is once again hunky-dory.  Damned frustrating.  It's too easy to blame
>>> the optimizer.  Anybody have any generic advice on what to look for in
>>> such a situation?

>> Remove the write statement and compile with -Wall -fcheck=all.  This
>> might find where you are stomping on memory.

> I would add -Werror. If you always compile without warnings, your life will be simpler.

Oh, that's a deadly option for me. I use A LOT of implicit type conversion,
such as doing a calculation internally using double precision, but saving
the result in single precision, such as

snglz = dblex * dbley

-Werror is happy if an explicit REAL() is used. For the single precision
version of the real component of a double complex number, one needs to use
REAL(REAL(dblecmplx)) to make -Werror happy.

> If the presumably unlikely event that you're not already using IMPLICIT NONE in every program unit, I would do that, too.

I'm pretty religious about using IMPLICIT NONE in production code.

> Among the other things mentioned, a WRITE statement might mask problems caused by a variable that's not assigned a value before it's
> used.

Intriguing. How would that work? I've been trying to visualize how the
addition of a WRITE statement could change the computation.
>
> If all else fails, the debugger is your friend. If you haven't experienced the thrill of stepping through assembler instructions
> finding where your wayward variable is stored and examining its value and figuring out how it got to be what it is, this could be
> your chance.

I haven't used a real GUI debugger since the days of WATCOM on OS/2. If
only gfortran had something like that on Windows.


Dave Tholen

unread,
Jul 17, 2022, 10:01:30 AM7/17/22
to
>>>>>> If you read (sequentially) past the end-of-file, gfortran sets the value
>>>>>> of IOSTAT to -1, but if you read a second time, gfortran sets the value
>>>>>> of IOSTAT to 5001. I discovered this situation after having written a
>>>>>> program expecting subsequent READs to all return a negative number, and
>>>>>> of course the program didn't behave as expected until I investigated the
>>>>>> problem. So I'm curious as to why the choice was made to have IOSTAT
>>>>>> set to something other than -1 on any READ attempt after the end-of-file
>>>>>> condition has been triggered. Isn't the file pointer still just beyond
>>>>>> the last record in the file, even after the first failed READ?

>>>>> You are expected to test for IOSTAT and deal with the end-of-file condition.
>>>>> You are not expected to continue reading the file.
>>>> I actually do test for IOSTAT and deal with the end-of-file condition by
>>>> exiting the DO loop with the READ statement. But once the DO loop has
>>>> been exited, the program is in an outer DO loop, which can also read the
>>>> file.

>>> You need to fix the logic.

>> Apparently I haven't been clear.
>> The program has already been fixed.

> But it hasn't been fixed.

Incorrect; reread my previous statement.

> You admitted it.

Incorrect.

> You said that after detecting end of file using IOSTAT, you exited the loop,
> and the outer loop then proceeded to execute READs on the same file.

That was before the fix. Now it is using a named DO loop, and when
the data-reading DO loop encounters the end-of-file condition, it
exits the outer DO loop, so the outer DO loop's READ statement is
not encountered. That made the value of IOSTAT in the outer DO loop
irrelevant. However, that I succeeded in making my program work
properly did not change my curiosity as to why the value of IOSTAT
changed upon the second end-of-file READ.

>> It was fixed before I even posted on this forum. The question is not
>> how to fix the problem. The question is why the value of IOSTAT was
>> changed.

> That has already been explained to you.

Where? The closest anyone has come is Steve Lionel, who said he could
make an argument for the second instance not being -1, but he didn't
present that argument. That ifort returns -1 upon a second READ
demonstrates that the situation is "processor dependent".

>> There must be some rationale.

>>>> It also tests IOSTAT to deal with the end-of-file condition,

>>> The program has already hit the end of file.
>>> Now you are trying to read read the same file at the same place.

>> That's just it: same file, same place, same action, yet a different
>> IOSTAT result. Not what I had expected.

> Again, that has been explained to you.

Again, where?

>>>> but
>>>> it tested for a negative number, which IOSTAT was no longer set to.

>>> You need to avoid reading after end of file has been detected.

>> Why? IOSTAT was added so that a program could handle error conditions.

> Provided that you deal with the condition and do not do silly things like reading
> the same file again, after detecting end-of file.

Hardly silly, given that reading the same file again just triggers yet another
error condition, and IOSTAT was designed to allow programs to deal with the
error condition.

>> My program was designed to deal with the error condition. Had gfortran
>> consistently returned a negative IOSTAT for every attempt to READ past
>> the end-of-file, my program would have worked exactly as intended.

> Listen up. Your program is in error. Fix it.

Listen up: you are incorrect. My program *WAS* incompatible with gfortran's
handling of a second end-of-file READ. However, my program *WAS* compatible
with ifort's handling of a second end-of-file READ. My program *IS* no longer
incompatible with either compiler, and that was the case before I even
posted on this forum. Get your tenses straight.

>> Had I used ifort, my program would have worked exactly as intended.

>>>> And if you must know why the nested DO loops, one loop dealt with data
>>>> while the other loop dealt with metadata. It was easily fixable. My
>>>> question here was not about how to fix the problem, but rather to find
>>>> out the rationale for changing the value of IOSTAT in such a situation.
>>>> My expectation was that IOSTAT would remain negative. My expectation
>>>> was wrong, hence the curiosity.

>>>>>> On a completely separate matter, I have a different program that
>>>>>> didn't behave as expected, and that misbehavior was totally repeatable.
>>>>>> In an attempt to debug the program, I added a WRITE statement to check
>>>>>> on the value of a variable during execution. However, once the WRITE
>>>>>> statement was added, the program started behaving properly, repeatably.

>>>>> That suggests that there is a bug in your program.

>>>> Brilliant.

>>>>> Possibly something has
>>>>> been overwritten.

>>>> I already thought about that, hence the WRITE statement to examine
>>>> the values of the array indices.

>>> In every program unit, subroutine and function in the entire program?

>> I usually sprinkle WRITE statements around to isolate where the crash
>> is happening. As I narrow things down, unnecessary WRITE statements are
>> either removed or commented out. In this particular case, I got it down
>> to a single WRITE statement that could trigger proper behavior.

> You program has errors.

Perhaps. I doubt anyone can guarantee that the optimizer has zero bugs.
It wouldn't be the first time I've encountered a bug in an optimizer.
Clearly there is a bug somewhere, but you can't guarantee that it is in
my code.

> Find them with the help of debug options
> such as subscript bound errors, substring errors, and the like.

The WRITE statements showed that my subscripts are within bounds.
Substrings are not involved.

>>>> The values were within range and
>>>> the program worked properly with the WRITE statement enabled. Comment
>>>> out the WRITE statement, and the misbehavior returned. Hence the
>>>> frustration.

>>>>> Turn on subscript bounds checking (if available).
>>>>> And while you're at it, turn on all checks.

Dave Tholen

unread,
Jul 17, 2022, 10:02:53 AM7/17/22
to
>> So, you're saying that if my program has subprograms A, B, C, D, and E,
>> and the crash occurs while it's executing subprogram C, the apparent
>> overwriting could be in A, B, D, or E?

> The error could be in any of A, B, C, D, E, and/or the main program.

Can you provide an example?

FortranFan

unread,
Jul 17, 2022, 10:31:41 AM7/17/22
to
On Sunday, July 17, 2022 at 6:13:50 AM UTC-4, Dave Tholen wrote:

> ..
> I haven't used a real GUI debugger since the days of WATCOM on OS/2. If
> only gfortran had something like that on Windows.

@Dave Tholen,

Re: "real GUI debugger" on Windows, you have a couple of options;

1. In the FOSS space, take a look at CodeBlocks::Fortran: there are also brief instructions, videos (e.g., YouTube) online as to how to use the graphical debugging capabilities with gfortran.
https://cbfortran.sourceforge.io/

2. In the complimentary software space, you may want to consider "Community" edition of Microsoft Visual Studio that you may be able to use without having to pay for a license. You can then look at Intel oneAPI HPC toolkit which now offers two Fortran compilers, IFORT and Intel's new LLVM based IFX, for free
https://visualstudio.microsoft.com/vs/community/
https://www.intel.com/content/www/us/en/developer/tools/oneapi/hpc-toolkit.html#gs.6kfdva

With Visual Studio IDE + Intel Fortran compilers, you can gain a real GUI debugging experience on Windows. Though there are some exasperating gaps and issues with this integration, they only come into play with a lot of modern Fortran features or use in a heavy-duty usage in a commercial big software type of setting where personal productivity demands are high.

FortranFan

unread,
Jul 17, 2022, 10:35:22 AM7/17/22
to
On Sunday, July 17, 2022 at 10:02:53 AM UTC-4, Dave Tholen wrote:

> ..
> Can you provide an example?

@Dave Tholen,

If your interest is in gaining some insight and answers as opposed to an open-ended discussion, you may also want to post at the Fortran Discourse site:
https://fortran-lang.discourse.group/

And consider posting there first *your own small example* that illustrates what you are doing in your code.

Ron Shepard

unread,
Jul 17, 2022, 12:18:18 PM7/17/22
to
On 7/15/22 6:47 AM, Dave Tholen wrote:
> If you read (sequentially) past the end-of-file, gfortran sets the value
> of IOSTAT to -1, but if you read a second time, gfortran sets the value
> of IOSTAT to 5001. I discovered this situation after having written a
> program expecting subsequent READs to all return a negative number, and
> of course the program didn't behave as expected until I investigated the
> problem. So I'm curious as to why the choice was made to have IOSTAT
> set to something other than -1 on any READ attempt after the end-of-file
> condition has been triggered. Isn't the file pointer still just beyond
> the last record in the file, even after the first failed READ?

As others have explained, this dates back to when files were mostly
stored and accessed on magnetic tape. There were separate end-of-record
EOR and end-of-file EOF markers that were written to the tape, and you
could have separate files stored on a single tape, one after another.
The logical way to think of this is that each write to the tape would
write the data, followed by the EOR mark, followed by the EOF mark, and
then the tape was positioned to right before the EOF mark. If subsequent
records were written, they would overwrite the old EOF mark. If the tape
was rewound or unmounted or backspaced, or anything else, then that old
EOF mark would be there for the next time the tape was mounted or
positioned at that point.

After the last record in a tape file was read, a subsequent read would
detect the EOF mark on the tape. That information was returned through
the end= branch in the read statement or through the IOSTAT variable.

Once that happened, there were several things that could occur. One of
them was that you could read the next file. That next file might have
different record lengths, or it could have different
formatted/unformatted status, and so on, so the program needed some
ability to change those characteristics. This was all done in
nonportable, machine-specific ways before f77, and then f77 introduced
OPEN, CLOSE, and INQUIRE to make it more portable. But it was sometimes
still difficult to do things like this in a portable way.

Another thing that you could do was to BACKSPACE on the unit to move the
tape back to right before the EOF mark. From there, you could append
more records to that file. Of course not all files were stored on
magnetic tapes. There were other devices including paper tape, cards,
drums, disks, and now in modern times various kinds of solid state
devices and network file systems and so on. But the language allowed
these newer devices to look like they were magnetic tapes, so all this
stuff about records and EOR and EOF marks was still retained.

However, this one thing about EOF marks was not always done
consistently. In f77, the only way to append to a file was to read
records until the end= or IOSTAT value indicated that the file was
beyond the virtual EOF mark. From there, you were supposed to be able to
BACKSPACE the unit and then append new records. But many machines did
not do this correctly. There was often no actual EOF record written to
the file, and instead the end= condition was triggered when the file
pointer was at the end of the filesystem metadata for that file. On
these machines, no BACKSPACE was required, you could just start writing
the new records at that point. And even worse, if you did BACKSPACE, in
what should have been the correct instruction sequence, it would
backspace over the last record in the file. Then when you wrote the new
records, you would lose the information in that last record and the
record counts thereafter would all be off by one. So for the 1980s and
even 1990s, a cautious programmer had to test for this condition and
only do the BACKSPACE conditionally. I have not tested this recently,
but I expect it still happens when one tries to append to a file that
has been positioned with end=.

F90 allowed a file to be opened and positioned appropriately to append
new records. So the conditional BACKSPACE code could be replaced with
this new portable functionality.

So for your question, it is because EOF is not treated as an error
condition. It is intended to be a normal situation that a programmer can
encounter, detect, and continue processing accordingly in a portable
way. However, reading or writing past the EOF might or might not be
allowed on a given device, or for a file on some device. If it is not
allowed, then it is an error condition, an exceptional situation that
should not be normally encountered.


> On a completely separate matter, I have a different program that
> didn't behave as expected, and that misbehavior was totally repeatable.
> In an attempt to debug the program, I added a WRITE statement to check
> on the value of a variable during execution. However, once the WRITE
> statement was added, the program started behaving properly, repeatably.
> Comment out the added WRITE statement, and the program once again
> misbehaves, repeatedly. Re-enable the WRITE statement, and everything
> is once again hunky-dory. Damned frustrating. It's too easy to blame
> the optimizer. Anybody have any generic advice on what to look for in
> such a situation?

These are called 'Heisenbugs'. The program is corrupting either the data
or the stored instruction code somehow. It could be caused by
out-of-range array indexing, or by some illegal argument mismatch (e.g.
a scalar actual argument associated with a dummy array argument), or
referencing an undefined or stale pointer, or maybe by switching the
order of some arguments that otherwise pass the type-kind-rank (TKR)
detection that the compiler can detect (an example might be switching
row and column indices of an array). The difficult thing about locating
these types of errors is that the backtrace does not always occur right
when the error occurs. The corruption can occur at one point, then then
execution can continue for some time before that data is accessed or
those instructions are executed.

These bugs were quite common before f90. F90 introduced several new
features that help to detect or eliminate these errors. These include
TKR checking for subroutines that have explicit interfaces, assumed
shape array declarations, the IMPLICIT NONE declaration (which helps
eliminate local variables that arise because of typos and misspellings),
and free-form source (which eliminates errors due to running past column
72 in the older fixed-form source). If you are writing new code, then
try to use these features. If you are working with legacy code, then you
might try moving some of the newer features into the code in order to
get some help from the compiler. Of course, modern fortran also has new
ways to introduce Heisenbugs, such as pointers which can become stale
and reference data that no longer exists in memory.

$.02 -Ron Shepard


Robin Vowels

unread,
Jul 17, 2022, 12:54:11 PM7/17/22
to
.
IOSTAT was added so that end-of-file could be detected and dealt with.
IOSTAT was also added so that error conditions could be detected.
[Note that end-of-file is not considered to be an error condition.]
.
> > Provided that you deal with the condition and do not do silly things like reading
> > the same file again, after detecting end-of file.

> Hardly silly, given that reading the same file again just triggers yet another
> error condition,
.
No it doesn't. Reading the same file again after end of file has been detected
is the first error condition raised.
.
IOSTAT returns a negative value for end of file.
IOSTAT returns a positive integer for an error condition.
.
> and IOSTAT was designed to allow programs to deal with the
> error condition.
>
> >> My program was designed to deal with the error condition. Had gfortran
> >> consistently returned a negative IOSTAT for every attempt to READ past
> >> the end-of-file, my program would have worked exactly as intended.
>
> > Listen up. Your program is in error. Fix it.
> Listen up: you are incorrect.
.
I am not incorrect. Read the standard.
.
> My program *WAS* incompatible with gfortran's
> handling of a second end-of-file READ.
.
No, your program was wrong.
.
Your program was in error when you tried to read the file again,
after receiving end-of-file notification.
That's why you received a positive number for IOSTAT when you tried
to read the file after receiving end-of-file.
.
> > Your program has errors.
>
> Perhaps. I doubt anyone can guarantee that the optimizer has zero bugs.
.
It's common for people to blame the compiler when their program does not work,
especially when they do not bother to read the manual.

> It wouldn't be the first time I've encountered a bug in an optimizer.
> Clearly there is a bug somewhere, but you can't guarantee that it is in
> my code.
.
Can you guarantee that the bug(s) is not in your code?
.
> > Find them with the help of debug options
> > such as subscript bound errors, substring errors, and the like.
> The WRITE statements showed that my subscripts are within bounds.
.
That's not the same as enabling subscript checks and all other checks.

FortranFan

unread,
Jul 17, 2022, 2:48:12 PM7/17/22
to
On Sunday, July 17, 2022 at 12:18:18 PM UTC-4, Ron Shepard wrote:

> ..
> So for your question, it is because EOF is not treated as an error
> condition. It is intended to be a normal situation that a programmer can
> encounter, detect, and continue processing accordingly in a portable
> way. However, reading or writing past the EOF might or might not be
> allowed on a given device, or for a file on some device. If it is not
> allowed, then it is an error condition, an exceptional situation that
> should not be normally encountered. ..

@Dave Tholen,

You may want to take note with current Fortran, it will help to not deal directly with specific values of IOSTAT but to take a higher level view of them.

You may know Fortran now includes an intrinsic module ISO_FORTRAN_ENV which makes available via USE association among other entities also two named constants, IOSTAT_END and IOSTAT_EOR.

You may find it helpful to keep in mind the following when using data transfer statements and IOSTAT= optional parameter is being used; just an example, say with IOSTAT=ISTAT in READ and WRITE statements:

1. ISTAT == 0 applies to a data transfer when no exception condition has occurred, business as usual,
2. ISTAT == IOSTAT_END corresponds to an end-of-file condition. Note this is separate from an error,
3. ISTAT == IOSTAT_EOR corresponds to an end-of-record condition; particularly relevant to direct-access IO where RECL (record-length) is involved,
4. ISTAT equal to anything else corresponds to an IO error condition.

With above, whether the specific value of ISTAT following a data transfer is -1 or 5001 does not quite matter, what is relevant is where the ISTAT value falls in the above listed situations 1 thru' 4.

Someone with gfortran expertise can shed further light, but if you really wish to get into -1 vs 5001 in the READ you did with gfortran after the EOF was encountered, perhaps the following from the standard might help explain:

"If an end-of-file condition occurs during execution of an input/output statement that contains either an END= specifier or an IOSTAT= specifier, and an error condition does not occur then:

(1) processing of the input list, if any, terminates;
(2) if the statement is a data transfer statement or the end-of-file condition occurs during a wait operation,
all do-variables in the statement that initiated the transfer become undefined;
(3) if the statement is an input statement or the end-of-file condition occurs during a wait operation
for a transfer initiated by an input statement, all effective items resulting from the expansion of list
items or the namelist group in the statement that initiated the transfer become undefined;
(4) if the file specified in the input statement is an external record file, it is positioned after the endfile record;"

See point (4). Given such positioning, it does not make sense the subsequent READ you attempt on the same unit should lead to an EOF situation i.e., the ISTAT thus cannot be IOSTAT_END again.

John

unread,
Jul 17, 2022, 5:17:16 PM7/17/22
to
I think about half of this would have been clarified by actually using the IOMSG= feature, which I did not find actually being used?
A simple example program demonstrates several of the points mentioned early on ....

cat /tmp/xp.f90
program testit
implicit none
integer :: iostat,i
character(len=256) :: iomsg,line
do i=1,10
read(*,*,iostat=iostat,iomsg=iomsg)line
if(iostat.ne.0)then
write(*,*)iostat,trim(iomsg)
else
write(*,*)'i=',i,trim(line)
endif
enddo


end program testit

$ xp </dev/null
-1 End of file
5001 Sequential READ or WRITE not allowed after EOF marker, possibly use REWIND or BACKSPACE

If you create a file with three lines
file1
ctrl-Z
file2

where ctrl-Z is literally the character ctrl-Z and try it with different compilers, you will find some compilers treat the ctrl-Z as an end-of-file that you can read past even on Linux platforms (an extension in my opinion); that after the first EOF the message changes and in some cases remains a -1 and in others does not. These are all acceptable behaviors if someone surprising in some cases as the standard is not specific about exactly what an EOF is; and at least one compiler appears to treat the ctrl-Z as an EOF only for formatted sequential I/O when the ctrl-Z is on a "line" by itself. All dependably return a value matching IOSTAT_END the first time they encounter what they define as an end-of-file.

But for the specific question about why -1 and 5001 tfor gfortran he IOMSG text seems quite self-explanatory and standard-conforming.
Remember that if you are not trapping the IOSTAT value the messages returned in IOMSG generally appear on stderr and the program ends
on error.



Dave Tholen

unread,
Jul 17, 2022, 7:49:52 PM7/17/22
to
But another READ past the end-of-file apparently is considered to be an
error condition by gfortran, whereas ifort apparently considers it to be
an end-of-file condition.

>>> Provided that you deal with the condition and do not do silly things like reading
>>> the same file again, after detecting end-of file.

>> Hardly silly, given that reading the same file again just triggers yet another
>> error condition,

> No it doesn't. Reading the same file again after end of file has been detected
> is the first error condition raised.

You don't know that. In fact, if you read elsewhere in this thread, you'd
know that the data file uses the characters "null" in place of a missing
numerical value, which triggers multiple error conditions long before a
second end-of-file READ occurs. It's hardly the first error condition
raised.

> IOSTAT returns a negative value for end of file.
> IOSTAT returns a positive integer for an error condition.

Yet ifort returns -1 for a second end-of-file READ while gfortran returns
5001. Are you arguing that one of the two compilers is not standard
compliant?

>> and IOSTAT was designed to allow programs to deal with the
>> error condition.

>>>> My program was designed to deal with the error condition. Had gfortran
>>>> consistently returned a negative IOSTAT for every attempt to READ past
>>>> the end-of-file, my program would have worked exactly as intended.

>>> Listen up. Your program is in error. Fix it.

>> Listen up: you are incorrect.

> I am not incorrect. Read the standard.

You are incorrect. My program is standard-conforming and works properly.

>> My program *WAS* incompatible with gfortran's
>> handling of a second end-of-file READ.

> No, your program was wrong.

Looks like you've finally admitted (tacitly) that you had your tenses wrong.
Given that the different compilers return IOSTAT values with different signs
for the same second end-of-file READ, it can be argued that the situation is
"processor dependent". Forty years ago, programs that OPENed a file and
started READing worked just fine with compilers that set the file pointer to
the beginning of the file, until they were moved to a BSD UNIX system whose
compiler, by default, OPENed a file with the pointer at the end of the file.
The program wasn't "wrong"; rather, it was incompatible with a processor
dependency.

> Your program was in error when you tried to read the file again,
> after receiving end-of-file notification.

Rather, an error condition was triggered when the program tried to read
the file again, but the code included a test on the value of IOSTAT to
deal with the condition.

> That's why you received a positive number for IOSTAT when you tried
> to read the file after receiving end-of-file.

Yet ifort returns a negative number. Are you arguing that ifort is in
error?
>>> Your program has errors.

>> Perhaps. I doubt anyone can guarantee that the optimizer has zero bugs.

> It's common for people to blame the compiler when their program does not work,
> especially when they do not bother to read the manual.

Hence why I wrote "It's too easy to blame the optimizer."

>> It wouldn't be the first time I've encountered a bug in an optimizer.
>> Clearly there is a bug somewhere, but you can't guarantee that it is in
>> my code.

> Can you guarantee that the bug(s) is not in your code?

Obviously not, hence my request for "generic advice on what to look for in
such a situation."

Why continue to ask questions for which answers have already been provided?

>>> Find them with the help of debug options
>>> such as subscript bound errors, substring errors, and the like.

>> The WRITE statements showed that my subscripts are within bounds.

> That's not the same as enabling subscript checks and all other checks.

It is the same as checking for subscript bound errors.

Dave Tholen

unread,
Jul 17, 2022, 7:57:56 PM7/17/22
to
>> Can you provide an example?

> If your interest is in gaining some insight and answers as opposed to an open-ended discussion, you may also want to post at the Fortran Discourse site:
> https://fortran-lang.discourse.group/

Are you suggesting that fortran-lang.discourse.group is for insight and that
comp.lang.fortran is for open-ended discussions?

> And consider posting there first *your own small example* that illustrates what you are doing in your code.

You're assuming that the problem can be reproduced with a "small example".
The program isn't small. If the simple addition of a WRITE statement can
trigger correct behavior, shrinking of the task to a "small example" will
lead to massive changes that more than likely will also eliminate the bug,
especially if the bug is NOT in the subprogram where the crash occurs.

Louis Krupp

unread,
Jul 17, 2022, 10:26:40 PM7/17/22
to
You might be able to silence conversion warnings. This code, for example:

===
subroutine s(xi, xo)

implicit none

double precision, intent(in) :: xi
real, intent(out) :: xo

xo = xi

return
end
===

compiles quietly with these options:

gfortran -c -Wall -Wno-conversion -Werror ...

>> If the presumably unlikely event that you're not already using
>> IMPLICIT NONE in every program unit, I would do that, too.
>
> I'm pretty religious about using IMPLICIT NONE in production code.
>
>> Among the other things mentioned, a WRITE statement might mask
>> problems caused by a variable that's not assigned a value before it's
>> used.
>
> Intriguing.  How would that work?  I've been trying to visualize how the
> addition of a WRITE statement could change the computation.

Don't even try to visualize it. Some things become clear only in
retrospect, and this could be one of them.

I have seen apparently unrelated code changes move variables from
registers to memory, and that can trigger the difference between an
uninitialized variable accidentally inheriting garbage instead of the
zero value the programmer was expecting. Sometimes there's a chain of
events.

I vaguely recall a post from a year or two ago in which a subprogram
ignored the value of an argument that had been declared INTENT(OUT). The
results were standard-compliant but surprising.

On the off chance that your compiler is misbehaving or perhaps not
issuing a warning when it should, are you running the latest version of
gfortran?

gah4

unread,
Jul 17, 2022, 11:22:33 PM7/17/22
to
On Sunday, July 17, 2022 at 11:48:12 AM UTC-7, FortranFan wrote:

(snip)

> "If an end-of-file condition occurs during execution of an input/output statement that contains either an END= specifier or an IOSTAT= specifier, and an error condition does not occur then:

> (1) processing of the input list, if any, terminates;
> (2) if the statement is a data transfer statement or the end-of-file condition occurs during a wait operation,
> all do-variables in the statement that initiated the transfer become undefined;
> (3) if the statement is an input statement or the end-of-file condition occurs during a wait operation
> for a transfer initiated by an input statement, all effective items resulting from the expansion of list
> items or the namelist group in the statement that initiated the transfer become undefined;
> (4) if the file specified in the input statement is an external record file, it is positioned after the endfile record;"

Those are useful, but there are also ones that apply for I/O errors.

I believe, like (3), in the case of I/O error that all the I/O list elements are undefined.

For comparison, in C all I/O elements before EOF or any other condition occurs are
not undefined, but have the appropriate value. That can be very convenient.


Robin Vowels

unread,
Jul 18, 2022, 12:05:23 AM7/18/22
to
Since you have not read the standard, you do not know whether your program
is "standard conforming".
>
> >> My program *WAS* incompatible with gfortran's
> >> handling of a second end-of-file READ.
> > No, your program was wrong.
> Looks like you've finally admitted (tacitly) that you had your tenses wrong.
> Given that the different compilers return IOSTAT values with different signs
> for the same second end-of-file READ, it can be argued that the situation is
> "processor dependent".
>
All the IOSTAT values are processor-dependent (except for zero).
However, the value returned for end-of-file is negative.
The value for an error condition is positive.
This infrioation is in the standard.
>
> Forty years ago, programs that OPENed a file and
> started READing worked just fine with compilers that set the file pointer to
> the beginning of the file, until they were moved to a BSD UNIX system whose
> compiler, by default, OPENed a file with the pointer at the end of the file.
> The program wasn't "wrong"; rather, it was incompatible with a processor
> dependency.
> > Your program was in error when you tried to read the file again,
> > after receiving end-of-file notification.
> Rather, an error condition was triggered when the program tried to read
> the file again,

And because your program contains an error, it is not standard conforming.

but the code included a test on the value of IOSTAT to
> deal with the condition.
> > That's why you received a positive number for IOSTAT when you tried
> > to read the file after receiving end-of-file.
>
> Yet ifort returns a negative number. Are you arguing that ifort is in
> error?
>
ifort is in error.
You still have not read the standard.
Then why don't you act on that advice?
That advice has been given to you several times by various people.
>
> Why continue to ask questions for which answers have already been provided?
>
Why do you continue to ignore the advice that you have been
given? And keep asking the same questions?
>
> >>> Find them with the help of debug options
> >>> such as subscript bound errors, substring errors, and the like.
>
> >> The WRITE statements showed that my subscripts are within bounds.
>
> > That's not the same as enabling subscript checks and all other checks.
>
> It is the same as checking for subscript bound errors.
>
But your kind of error can be caused by many things besides
subscript errors.

FortranFan

unread,
Jul 18, 2022, 12:16:27 AM7/18/22
to
On Sunday, July 17, 2022 at 7:57:56 PM UTC-4, Dave Tholen wrote:

> ..
> Are you suggesting that fortran-lang.discourse.group is for insight and that
> comp.lang.fortran is for open-ended discussions?

@Dave Tholen,

You have to know the primarily text-based platform of comp.lang.fortran and the intricacies with Google Groups and Usenet readers, etc. becomes challenging to a certain crucial set of Fortranners who have backgrounds in certain tools and techniques toward Fortran. This group now volunteers their time at a far greater rate at the Fortran Discourse site where one can also post Fortran code with syntax highlighting, insert images, etc. The latter facilities can be "worth more than a thousand words". Hence the suggestion to you to also consider the Fortran Discourse site. The text-driven nature of comp.lang.fortran does appear to me to lead toward open-ended discussions around Fortran's past, previous hardware, etc.

> > And consider posting there first *your own small example* that illustrates what you are doing in your code.
> You're assuming that the problem can be reproduced with a "small example".
> The program isn't small. If the simple addition of a WRITE statement can trigger correct behavior ..

You write in your original post, "I have a different program that didn't behave as expected, and that misbehavior was totally repeatable. In an attempt to debug the program, I added a WRITE statement to check on the value of a variable during execution. However, once the WRITE statement was added, the program started behaving properly, repeatably. Comment out the added WRITE statement, and the program once again misbehaves, repeatedly. Re-enable the WRITE statement, and everything is once again hunky-dory. Damned frustrating. It's too easy to blame the optimizer. Anybody have any generic advice on what to look for in such a situation?"

Based on my own experience, a bug in code is what I would investigate thoroughly in such circumstances. Though a compiler problem cannot be discarded, I personally would only start looking toward the compiler after I have exhausted my analysis of the code. Chances are high that you will need to share more details if you would like further advice from readers.

Dave Tholen

unread,
Jul 20, 2022, 7:00:10 AM7/20/22
to
You wrote "the" standard as if there has been only one. In reality, there
have been multiple Fortran standards. I have a hardcopy of one of the
earlier standards and have read it. I have reference manuals to multiple
more recent compilers and I have read them as well. Since you do not know
the standard to which my program was written, and you also don't know which
of the standards or reference manuals I have read, you're not in a position
to make the claim that you did.

>>>> My program *WAS* incompatible with gfortran's
>>>> handling of a second end-of-file READ.

>>> No, your program was wrong.

>> Looks like you've finally admitted (tacitly) that you had your tenses wrong.
>> Given that the different compilers return IOSTAT values with different signs
>> for the same second end-of-file READ, it can be argued that the situation is
>> "processor dependent".

> All the IOSTAT values are processor-dependent (except for zero).
> However, the value returned for end-of-file is negative.
> The value for an error condition is positive.
> This infrioation is in the standard.

Irrelevant, given that my program does not test for specific processor-dependent
values; rather, it tests for negative values. The outer DO loop's IOSTAT negative
value test has been superfluous since the program now exits the outer named DO loop
when the inner DO loop encounters the end-of-file condition.

>> Forty years ago, programs that OPENed a file and
>> started READing worked just fine with compilers that set the file pointer to
>> the beginning of the file, until they were moved to a BSD UNIX system whose
>> compiler, by default, OPENed a file with the pointer at the end of the file.
>> The program wasn't "wrong"; rather, it was incompatible with a processor
>> dependency.

>>> Your program was in error when you tried to read the file again,
>>> after receiving end-of-file notification.

>> Rather, an error condition was triggered when the program tried to read
>> the file again,

> And because your program contains an error, it is not standard conforming.

My program does not contain an error. The version that existed prior to me
even starting this thread contained an incompatibility with a gfortran
processor-dependent feature. The current version is compatible with
gfortran.

>> but the code included a test on the value of IOSTAT to
>> deal with the condition.

>>> That's why you received a positive number for IOSTAT when you tried
>>> to read the file after receiving end-of-file.

>> Yet ifort returns a negative number. Are you arguing that ifort is in
>> error?

> ifort is in error.

File a bug report for ifort, if you think it is in error. Don't be surprised
if the response is that when you read past the end-of-file, it is an
end-of-file condition, regardless of the number of times you do it.

> You still have not read the standard.

You are still incorrect. There are all sorts of situations that the standard
writers did not anticipate when the standards were written, hence the need for
"interpretations" from the standards committee.
What makes you think I haven't acted on that advice? In fact, if you had
bothered to comprehend the responses I've written, you'd know that I commented
on the effect of -Werror and found it a deadly option due to frequent use of
implicit type conversion. If I hadn't acted on the advice, I would not
have known about the effect it would have on compilation.

>> Why continue to ask questions for which answers have already been provided?

> Why do you continue to ignore the advice that you have been
> given?

But I haven't ignored the advice. What makes you think otherwise?

> And keep asking the same questions?

But I haven't been asking the same questions. What makes you think otherwise?

>>>>> Find them with the help of debug options
>>>>> such as subscript bound errors, substring errors, and the like.

>>>> The WRITE statements showed that my subscripts are within bounds.

>>> That's not the same as enabling subscript checks and all other checks.

>> It is the same as checking for subscript bound errors.

> But your kind of error can be caused by many things besides
> subscript errors.

My WRITE statements were not limited to the display of only subscript values.
The use of WRITE statements to check on the values of variables has served
me well for debugging purposes for decades. However, when the addition of a
WRITE statement makes a problem go away, one wonders how that can happen.

Dick Hendrickson

unread,
Jul 20, 2022, 11:59:35 AM7/20/22
to
There isn't much that can be done in recovering from I/O errors.

read(unit, IOSTAT = JJJ, ...) N, A(1,N), N, A(7,N), N, B(1,N)

There is no possible way to know what array elements are undefined if
jjj is non-zero.

And, if a magnetic tape goes into "stretch and then break" mode there's
no reason to think that the last few values read in are any good.

Dick Hendrickson

Louis Krupp

unread,
Jul 23, 2022, 10:18:25 PM7/23/22
to
On 7/20/2022 5:00 AM, Dave Tholen wrote:
> <snip>

> The use of WRITE statements to check on the values of variables has
> served
> me well for debugging purposes for decades.  However, when the
> addition of a
> WRITE statement makes a problem go away, one wonders how that can happen.

Arguing with Robin isn't going to help you fix the problem.

Wondering what might have gone wrong isn't going to help.

There is a path to a solution, painful as it might be:

1. Compile your code for debug. If the problem persists, that's a good
thing. If the problem goes away, you'll have to debug whatever version
fails.

2. Find a debugger. Even a command-line debugger will do. Step through
the code. Set breakpoints. Set watchpoints. Follow the leads, the
hunches, the blind alleys. This will be time-consuming and tedious. You
will hate your life. Everyone around you will hate your life. They may
even hate you. Don't give up.

3. If the code and the data are suitable for public viewing, and if
packaging everything so someone else can have a go at it is less painful
than step 2 above, then do that. There are people out there with the
requisite knowledge, experience and high tolerance for pain. When
someone figures it out, we'll all learn something.

Louis


Ron Shepard

unread,
Jul 24, 2022, 4:55:58 AM7/24/22
to
Here is another item to add to the list.

4. When you finally find the bug, it will be obvious, and you will
wonder why on earth you didn't see it immediately.


Thomas Koenig

unread,
Jul 24, 2022, 5:34:49 AM7/24/22
to
Dave Tholen <tho...@antispam.ham> schrieb:

> However, when the addition of a WRITE statement makes a problem
> go away, one wonders how that can happen.

That one is actually a textbook symptom of uninitialized variables
and/or buffer overruns. Adding a print statement will change the
memory layout of the program and the values of some stack variables
in unpredictable ways.

If you have that problem, try running your code on every compiler
you have with every debugging option turned on (including, but
not limited to, the -fsanitize options and the -finit-integer=
with gfortran and, if you have it, nagfor's -C=check=all and
-Ccheck=undefined), or run your code under valgrind.

Robin Vowels

unread,
Jul 25, 2022, 2:03:16 AM7/25/22
to
On Wednesday, July 20, 2022 at 9:00:10 PM UTC+10, Dave Tholen wrote:
>>>>> If you read (sequentially) past the end-of-file, gfortran sets the value
>>>>> of IOSTAT to -1, but if you read a second time, gfortran sets the value
>>>>> of IOSTAT to 5001. I discovered this situation after having written a
>>>>> program expecting subsequent READs to all return a negative number, and
>>>>> of course the program didn't behave as expected until I investigated the
>>>>> problem. So I'm curious as to why the choice was made to have IOSTAT
>>>>> set to something other than -1 on any READ attempt after the end-of-file
>>>>> condition has been triggered. Isn't the file pointer still just beyond
>>>>> the last record in the file, even after the first failed READ?

>>>> You are expected to test for IOSTAT and deal with the end-of-file condition.
>>>> You are not expected to continue reading the file.

>>> I actually do test for IOSTAT and deal with the end-of-file condition by
>>> exiting the DO loop with the READ statement. But once the DO loop has
>>> been exited, the program is in an outer DO loop, which can also read the
>>> file.

>> You need to fix the logic.

> Apparently I haven't been clear.
> The program has already been fixed.

It had NOT been fixed when you wrote the first paragraph above.
You wrote: "But once the DO loop has been exited, the program is in
an outer DO loop, which can also read the file."

>>>> The closest anyone has come is Steve Lionel, who said he could
>>>> make an argument for the second instance not being -1, but he didn't
>>>> present that argument. That ifort returns -1 upon a second READ
>>>> demonstrates that the situation is "processor dependent".

The situation is NOT "processor dependent". The actual numerical value
is processor dependent", but the sign of the value is NOT. The sign
is required to be positive. ifort is not standard-conforming.

> You wrote "the" standard as if there has been only one.

There have been a number of standards published.
All say the same thing about IOSTAT since the keyword
was introduced in FORTRAN 77 -- in regard to the
value returned for no errors (zero), end of file (a negative
value) and an error (a positive value).

> In reality, there
> have been multiple Fortran standards. I have a hardcopy of one of the
> earlier standards and have read it. I have reference manuals to multiple
> more recent compilers and I have read them as well. Since you do not know
> the standard to which my program was written, and you also don't know which
> of the standards or reference manuals I have read, you're not in a position
> to make the claim that you did.

What you say is irrelevant with regard to IOSTAT.

>>>> My program *WAS* incompatible with gfortran's
>>>> handling of a second end-of-file READ.

>>> No, your program was wrong.

>> Looks like you've finally admitted (tacitly) that you had your tenses wrong.
>> Given that the different compilers return IOSTAT values with different signs
>> for the same second end-of-file READ, it can be argued that the situation is
>> "processor dependent".

> All the IOSTAT values are processor-dependent (except for zero).
> However, the value returned for end-of-file is negative.
> The value for an error condition is positive.
> This information is in the standard.

> Irrelevant,

It's very relevant, since you were testing for an IOSTAT value
of the wrong sign.

>>> given that my program does not test for specific processor-dependent
>>> values; rather, it tests for negative values. The outer DO loop's IOSTAT negative
>>> value test has been superfluous since the program now exits the outer named DO loop
>>> when the inner DO loop encounters the end-of-file condition.

>>> Forty years ago, programs that OPENed a file and
>>> started READing worked just fine with compilers that set the file pointer to
>>> the beginning of the file, until they were moved to a BSD UNIX system whose
>>> compiler, by default, OPENed a file with the pointer at the end of the file.
>>> The program wasn't "wrong"; rather, it was incompatible with a processor
>>> dependency.

>> Your program was in error when you tried to read the file again,
>> after receiving end-of-file notification.

>> Rather, an error condition was triggered when the program tried to read
>> the file again,

>> And because your program contains an error, it is not standard conforming.

> My program does not contain an error. The version that existed prior to me
> even starting this thread contained an incompatibility with a gfortran
> processor-dependent feature.
.
Your program contained an error. It first tested for a negative
value indicating end-of-file, and then attempted to read another
record that caused gfortran to return a positive value, indicating
an error condition. Your program expected another negative value,
instead of the positive vaue that was require by the Standard.
.
>>>> The current version is compatible with gfortran.

>>> but the code included a test on the value of IOSTAT to
>>> deal with the condition.

>>> That's why you received a positive number for IOSTAT when you tried
>>> to read the file after receiving end-of-file.

>> Yet ifort returns a negative number. Are you arguing that ifort is in
>> error?

> ifort is in error.

> File a bug report for ifort,

No, if you don't like it, you file a bug report with ifort.

> if you think it is in error. Don't be surprised
> if the response is that when you read past the end-of-file, it is an
> end-of-file condition, regardless of the number of times you do it.

You still have not read the standard. The Standard requires that
a Fortran compiler to return a positive value when a program attempts
to read past the end of file.

> You still have not read the standard.

>> You are still incorrect. There are all sorts of situations that the standard
>> writers did not anticipate when the standards were written, hence the need for
>> "interpretations" from the standards committee.

There is no need for an "interpretation". The standard is clear and unequivocal.
The standard has been around for 40 years.
.
>>>>> Find them with the help of debug options
>>>>> such as subscript bound errors, substring errors, and the like.

>>>> The WRITE statements showed that my subscripts are within bounds.

>>> That's not the same as enabling subscript checks and all other checks.

>> It is the same as checking for subscript bound errors.

No it's not. You could have missed printing one critial value,
or not realized that a subscript is out-of-range.

> But your kind of error can be caused by many things besides
> subscript errors.

> My WRITE statements were not limited to the display of only subscript values.

That's irrelevant.

> The use of WRITE statements to check on the values of variables has served
> me well for debugging purposes for decades. However, when the addition of a
> WRITE statement makes a problem go away, one wonders how that can happen.

I repeat: your kind of error can be caused by many things
besides subscript errors. You need to specify options that
check for ALL errors, including subscript errors.

Ron Shepard

unread,
Jul 25, 2022, 11:33:04 AM7/25/22
to
On 7/25/22 1:03 AM, Robin Vowels wrote:
> The situation is NOT "processor dependent". The actual numerical value
> is processor dependent", but the sign of the value is NOT. The sign
> is required to be positive. ifort is not standard-conforming.

Can you quote the standard, any version of the standard, that specifies
this? I do not think it is true for the reasons I explained previously
in this thread. If this were true, then there would be no way to read
multiple files from a magnetic tape. Yet at one time, that was a
routine, everyday, occurrence for fortran programmers.

$.02 -Ron Shepard

Message has been deleted

Peter Klausler US

unread,
Jul 25, 2022, 12:12:52 PM7/25/22
to
12.11.5 IOSTAT= specifier
1 Execution of an input/output statement containing the IOSTAT= specifier causes the stat-variable in the ISTAT= specifier to become defined with
• a zero value if neither an error condition, an end-of-file condition, nor an end-of-record condition occurs,
• the processor-dependent positive integer value of the constant IOSTAT_INQUIRE_INTERNAL_UNIT from the intrinsic module ISO_FORTRAN_ENV (16.10.2) if a unit number in an INQUIRE statement identifies an internal file,
• a processor-dependent positive integer value different from IOSTAT_INQUIRE_INTERNAL_UNIT if any other error condition occurs,
• the processor-dependent negative integer value of the constant IOSTAT_END (16.10.2.16) from the intrinsic module ISO_FORTRAN_ENV if an end-of-file condition occurs and no error condition occurs,

Robin Vowels

unread,
Jul 25, 2022, 12:25:15 PM7/25/22
to
On Tuesday, July 26, 2022 at 1:33:04 AM UTC+10, Ron Shepard wrote:
> On 7/25/22 1:03 AM, Robin Vowels wrote:
> > The situation is NOT "processor dependent". The actual numerical value
> > is processor dependent", but the sign of the value is NOT. The sign
> > is required to be positive. ifort is not standard-conforming.
.
> Can you quote the standard, any version of the standard, that specifies
> this?
.
ANSI X3.9-1978 Programming Language FORTRAN.
.
12.7

IOSTAT = ios

where ios is an integer variable or integer array element.

Execution of an input/output statement statement containing
this specifier causes ios to become defined:

(1) with a zero value if neither an error condition nor
an end-of-file condition is encountered by the processor.

(2) with a processor-dependent positive integer value if an
error condition is encountered, or

(3) with a processor-dependent negative integer value if
an end-of-file condition is encountered and no error
condition is encountered.
.

gah4

unread,
Jul 25, 2022, 2:04:19 PM7/25/22
to
Fortran 66, the version used when tapes were most popular, has no way
to detect EOF or ERR.

The END= and ERR= options, as well as I know, where added to IBM
Fortran IV, as extensions to Fortran 66. (Or maybe earlier, but that didn't
make it into the standard.) IBM is always good at marking the extensions
in their manual with a gray shading.

With OS/360 Fortran compilers, you use a DD statement in JCL for each
tape (or non-tape) file you want to read. It will first read from DDname
FTxxF001, where xx is the unit number. After the EOF exit, continued
reading is from FTxxF002. You can read many different disk data sets,
or sequential (or any order) tape data sets, with appropriate JCL.
For tapes, you need LABEL=(1,SL) for the first file on a standard
labelled tape (where the DSNAME must agree), and LABEL=(2,SL)
for the next one.

Or LABEL=(1,NL) for an unlabelled tape, or LABEL=(1,AL) for an
ANSI labelled tape. The latter worked with VAX, and also did
EBCDIC to/from ASCII translation.

So, the error case occurs when it tries to read a file that isn't
there, after the END= case. As well as I know, the standard
doesn't require that ability, but does allow for it.

Or it could immediately give END= for the (non-existent)
next file.

In any case, when IOSTAT is non-zero, either sign, the
standard makes all variables in the I/O list undefined.
Even the ones that might have been read before the
EOF or ERR condition.






Steve Lionel

unread,
Jul 25, 2022, 2:57:52 PM7/25/22
to
On 7/25/2022 2:03 AM, Robin Vowels wrote:
>>>>> The closest anyone has come is Steve Lionel, who said he could
>>>>> make an argument for the second instance not being -1, but he didn't
>>>>> present that argument. That ifort returns -1 upon a second READ
>>>>> demonstrates that the situation is "processor dependent".
> The situation is NOT "processor dependent". The actual numerical value
> is processor dependent", but the sign of the value is NOT. The sign
> is required to be positive. ifort is not standard-conforming.
>

I discussed this issue with Malcolm Cohen of NAG last week. He agreed
with me that continuing to read after the "ENDFILE record" has been
passed is an error, and NOT an end-of-file condition, therefore a
positive IOSTAT value is required. ifort is wrong here.

Note that you can BACKSPACE back to before the "ENDFILE record" (which
doesn't have to have a physical manifestation), and then get an endfile
condition again on a subsequent read.

While it was once common practice to read past tapemarks on unlabeled
magnetic tapes, that never became part of the Fortran standard.
--
Steve Lionel
ISO/IEC JTC1/SC22/WG5 (Fortran) Convenor
Retired Intel Fortran developer/support
Email: firstname at firstnamelastname dot com
Twitter: @DoctorFortran
LinkedIn: https://www.linkedin.com/in/stevelionel
Blog: https://stevelionel.com/drfortran
WG5: https://wg5-fortran.org


Robert Corbett

unread,
Jul 25, 2022, 5:40:03 PM7/25/22
to
I agree with you that attempting to read past the
endfile record of a sequential-access file is an
error, not an end-of-file condition. I do not agree
that it necessarily is an input/output error
condition. Subclause 12.11.1 of the Fortran 2018
standard states

The set of input/output error conditions is
processor dependent. Except as otherwise
specified, when an error condition occurs or
is detected is processor dependent.

Paragraph 2 of subclause 12.3.4.3 states

Input shall not occur if there is no next
record or if there is a current record and
the last data transfer statement accessing
the file performed output.

Nothing in that statement specifies that an
error condition occurs. It only says that a
program that tries to read a record that does
not exist is not a conforming program.

The Fortran standard explicitly does not
specify the behavior of programs that are
not standard conforming (see item 4 in the
list given in paragraph 4 of clause 1).
Therefore, a program that tries to read past
the end of the file could detect an
input/output error condition. It could detect
an end-of-file condition. It could detect an
end-of-record condition. It could read a record
from some other file.

There was once a proposal to codify the set of
input/output error conditions, but the effort did
not last long.

An attempt to read after an end-of-file
condition has occurred leads to unspecified
behavior.

gah4

unread,
Jul 25, 2022, 8:23:38 PM7/25/22
to
On Monday, July 25, 2022 at 2:40:03 PM UTC-7, Robert Corbett wrote:
> On Monday, July 25, 2022 at 11:57:52 AM UTC-7, Steve Lionel wrote:

(snip)
> > While it was once common practice to read past tapemarks on unlabeled
> > magnetic tapes, that never became part of the Fortran standard.

(snip)
> I agree with you that attempting to read past the
> endfile record of a sequential-access file is an
> error, not an end-of-file condition. I do not agree
> that it necessarily is an input/output error
> condition. Subclause 12.11.1 of the Fortran 2018
> standard states

(snip)
> Input shall not occur if there is no next
> record or if there is a current record and
> the last data transfer statement accessing
> the file performed output.

> Nothing in that statement specifies that an
> error condition occurs. It only says that a
> program that tries to read a record that does
> not exist is not a conforming program.

> The Fortran standard explicitly does not
> specify the behavior of programs that are
> not standard conforming (see item 4 in the
> list given in paragraph 4 of clause 1).
> Therefore, a program that tries to read past
> the end of the file could detect an
> input/output error condition. It could detect
> an end-of-file condition. It could detect an
> end-of-record condition. It could read a record
> from some other file.

Unix/C allows, and I presume is part of POSIX,
for a program to continue reading in case a file
size increases.

Specifically, that is used by the "tail -f" command
to follow writing to a file.

That is complicated by systems that do file locking,
but it works fine with Unix.

I am not so sure about the connection between
Fortran and POSIX.








Ron Shepard

unread,
Jul 26, 2022, 4:10:44 AM7/26/22
to
On 7/25/22 1:57 PM, Steve Lionel wrote:
> While it was once common practice to read past tapemarks on unlabeled
> magnetic tapes, that never became part of the Fortran standard.

I agree that fortran does not require this behavior, but I think the
current question is asking the other way. Did any Fortran standard ever
forbid it from occurring? I don't think it did, I think it left it as
processor dependent to first detect it as an error, and second which
positive error code to report if it was detected as an error. Doing this
makes sense for some devices, like magnetic tapes with multiple files,
or card decks with end-of-deck cards interspersed, but not others, like
a disk file system.

$.02 -Ron Shepard

Ron Shepard

unread,
Jul 26, 2022, 4:21:31 AM7/26/22
to
On 7/25/22 11:25 AM, Robin Vowels wrote:
> On Tuesday, July 26, 2022 at 1:33:04 AM UTC+10, Ron Shepard wrote:
>> On 7/25/22 1:03 AM, Robin Vowels wrote:
>>> The situation is NOT "processor dependent". The actual numerical value
>>> is processor dependent", but the sign of the value is NOT. The sign
>>> is required to be positive. ifort is not standard-conforming.
> .
>> Can you quote the standard, any version of the standard, that specifies
>> this?
> .
> ANSI X3.9-1978 Programming Language FORTRAN.
> .
> 12.7
>
> IOSTAT = ios
>
> where ios is an integer variable or integer array element.
>
> Execution of an input/output statement statement containing
> this specifier causes ios to become defined:
>
> (1) with a zero value if neither an error condition nor
> an end-of-file condition is encountered by the processor.
>
> (2) with a processor-dependent positive integer value if an
> error condition is encountered, or

This only occurs "if an error condition is encountered". The f77
standard does not specify that reading past an EOF marker is an error
condition. Neither does it specify that it is not an error condition.

$.02 -Ron Shepard

Robin Vowels

unread,
Jul 26, 2022, 6:29:24 AM7/26/22
to
On Tuesday, July 26, 2022 at 6:21:31 PM UTC+10, Ron Shepard wrote:
> On 7/25/22 11:25 AM, Robin Vowels wrote:
> > On Tuesday, July 26, 2022 at 1:33:04 AM UTC+10, Ron Shepard wrote:
> >> On 7/25/22 1:03 AM, Robin Vowels wrote:
> >>> The situation is NOT "processor dependent". The actual numerical value
> >>> is processor dependent", but the sign of the value is NOT. The sign
> >>> is required to be positive. ifort is not standard-conforming.
> > .
> >> Can you quote the standard, any version of the standard, that specifies
> >> this?
> > .
> > ANSI X3.9-1978 Programming Language FORTRAN.
> > .
> > 12.7
> >
> > IOSTAT = ios
> >
> > where ios is an integer variable or integer array element.
> >
> > Execution of an input/output statement statement containing
> > this specifier causes ios to become defined:
> >
> > (1) with a zero value if neither an error condition nor
> > an end-of-file condition is encountered by the processor.
> >
> > (2) with a processor-dependent positive integer value if an
> > error condition is encountered, or
.
> This only occurs "if an error condition is encountered". The f77
> standard does not specify that reading past an EOF marker is an error
> condition. Neither does it specify that it is not an error condition.
.
The F77 and subsequent standards specify two kinds of things:
1. an end-of-file condition;
2. an error condition.
If the event is not an end-of-file condition, it is therefore an error condition.
It is clear and unequivocal.

Robin Vowels

unread,
Jul 26, 2022, 6:36:30 AM7/26/22
to
On Tuesday, July 26, 2022 at 4:04:19 AM UTC+10, gah4 wrote:
.
> Fortran 66, the version used when tapes were most popular, has no way
> to detect EOF or ERR.
>
> The END= and ERR= options, as well as I know, where added to IBM
> Fortran IV, as extensions to Fortran 66. (Or maybe earlier, but that didn't
> make it into the standard.) IBM is always good at marking the extensions
> in their manual with a gray shading.

A good reason for using PL/I which, in 1966, treated routinely
end-of-file conditions [ ON ENDFILE (x) ... ] and error conditions
[ ON ERROR ... ]

> With OS/360 Fortran compilers, you use a DD statement in JCL for each
> tape (or non-tape) file you want to read. It will first read from DDname
> FTxxF001, where xx is the unit number. After the EOF exit, continued
> reading is from FTxxF002. You can read many different disk data sets,
> or sequential (or any order) tape data sets, with appropriate JCL.
> For tapes, you need LABEL=(1,SL) for the first file on a standard
> labelled tape (where the DSNAME must agree), and LABEL=(2,SL)
> for the next one.
>
> Or LABEL=(1,NL) for an unlabelled tape, or LABEL=(1,AL) for an
> ANSI labelled tape. The latter worked with VAX, and also did
> EBCDIC to/from ASCII translation.
>
> So, the error case occurs when it tries to read a file that isn't
> there, after the END= case. As well as I know, the standard
> doesn't require that ability, but does allow for it.
>
> Or it could immediately give END= for the (non-existent)
> next file.
>
> In any case, when IOSTAT is non-zero, either sign, the
> standard makes all variables in the I/O list undefined.
> Even the ones that might have been read before the
> EOF or ERR condition.
.
Another reason for using PL/I, in which variables already read
were stored, and the values of which were available.
.
FORTRAN did not have any of those facilities until more
than a decade later.

gah4

unread,
Jul 26, 2022, 8:04:00 AM7/26/22
to
As I note, with OS/360 Fortran you can have a different disk dataset
to be read after each EOF, with a different DD card. It did always
seem a strange system, as reading sequential files on a tape
seems more obvious.


Steve Lionel

unread,
Jul 26, 2022, 8:04:09 AM7/26/22
to
On 7/26/2022 4:10 AM, Ron Shepard wrote:
> On 7/25/22 1:57 PM, Steve Lionel wrote:
>> While it was once common practice to read past tapemarks on unlabeled
>> magnetic tapes, that never became part of the Fortran standard.
>
> I agree that fortran does not require this behavior, but I think the
> current question is asking the other way. Did any Fortran standard ever
> forbid it from occurring?

The Fortran standard isn't written that way - it describes a
standard-conforming program and what such a program is supposed to do. A
program that is written or behaves in a manner not specified by the
standard is non-conforming and its behavior is processor-dependent.

MIL-STD-1753 did specify that a read after EOF was permissible, but that
aspect never made it into the Fortran standard.

Ron Shepard

unread,
Jul 26, 2022, 11:34:58 AM7/26/22
to
On 7/26/22 5:29 AM, Robin Vowels wrote:
> On Tuesday, July 26, 2022 at 6:21:31 PM UTC+10, Ron Shepard wrote:
[...]
>>> Execution of an input/output statement statement containing
>>> this specifier causes ios to become defined:
>>>
>>> (1) with a zero value if neither an error condition nor
>>> an end-of-file condition is encountered by the processor.
>>>
>>> (2) with a processor-dependent positive integer value if an
>>> error condition is encountered, or
> .
>> This only occurs "if an error condition is encountered". The f77
>> standard does not specify that reading past an EOF marker is an error
>> condition. Neither does it specify that it is not an error condition.
> .
> The F77 and subsequent standards specify two kinds of things:
> 1. an end-of-file condition;
> 2. an error condition.
> If the event is not an end-of-file condition, it is therefore an error condition.
> It is clear and unequivocal.

Show in the text where these are the only two choices when an end of
file is encountered. I don't think it does, I think it leaves it
unspecified, and I think it did so purposefully in order to allow, but
not require, reading more than one file from a tape, card deck, etc.

$.02 -Ron Shepard

Ron Shepard

unread,
Jul 26, 2022, 11:39:38 AM7/26/22
to
On 7/26/22 5:36 AM, Robin Vowels wrote:
[...]

> A good reason for using PL/I which, in 1966, treated routinely
> end-of-file conditions [ ON ENDFILE (x) ... ] and error conditions
> [ ON ERROR ... ]

Just out of curiosity, would PL/I allow a programmer to read multiple
files from a magnetic tape. separated by end-of-file records, or to read
multiple files from a card deck that had end-of-deck cards interspersed
in the stack?

$.02 -Ron Shepard

Ron Shepard

unread,
Jul 26, 2022, 11:52:04 AM7/26/22
to
Yes, I agree, I was too generous with that example, I should have said
that "some disk file systems" do not allow it.

Regarding unix/POSIX disk file systems, it is required that utilities
like "tail -f" and "more" should be able to read files that are in the
process of being written. Those files do not really have an end-of-file
record, the end is determined by a file system parameter. When the file
pointer reaches that value, the utility sleeps and then wakes up and
checks again to see if more data has been written. So the underlying
model is different from a series of files written to magnetic tape. I'm
not certain, but I don't think "tail -f" or "more" would be required to
work that way on an actual magnetic tape device.

$.02 -Ron Shepard


Gary Scott

unread,
Jul 26, 2022, 11:52:51 AM7/26/22
to
Some OS' of the past supported multiple files on disk as well and
returned EOF followed by EOT for disk files with only one file.

> $.02 -Ron Shepard
>

Ron Shepard

unread,
Jul 26, 2022, 11:58:34 AM7/26/22
to
On 7/26/22 7:04 AM, Steve Lionel wrote:
> On 7/26/2022 4:10 AM, Ron Shepard wrote:
>> On 7/25/22 1:57 PM, Steve Lionel wrote:
>>> While it was once common practice to read past tapemarks on unlabeled
>>> magnetic tapes, that never became part of the Fortran standard.
>>
>> I agree that fortran does not require this behavior, but I think the
>> current question is asking the other way. Did any Fortran standard
>> ever forbid it from occurring?
>
> The Fortran standard isn't written that way - it describes a
> standard-conforming program and what such a program is supposed to do. A
> program that is written or behaves in a manner not specified by the
> standard is non-conforming and its behavior is processor-dependent.
>
> MIL-STD-1753 did specify that a read after EOF was permissible, but that
> aspect never made it into the Fortran standard.

This is the sometimes subtle distinction between a nonconforming program
that violates some aspect of the standard and one that is rather
unspecified by the standard. My question regarding reading past an end
of file marker was exactly that point. I think the fortran standard (in
contrast to the MIL-STD standard) never specified that behavior one way
or the other. Others in this discussion are claiming that it was
specifically forbidden and that positive IOSTAT values must be returned.

$.02 -Ron Shepard

Robin Vowels

unread,
Jul 26, 2022, 12:51:09 PM7/26/22
to
.
I already have. See my earlier post where the three alternatives are
enunciated.

John

unread,
Jul 30, 2022, 6:00:41 PM7/30/22
to

John

unread,
Jul 30, 2022, 6:19:39 PM7/30/22
to
A number of environments support multi-file formats MSWindows uses ctrl-Z (the EOF character). in formatted files as a file separator and lets you continue reading, gfortran does not appear to allow you to read past the ctrl-Z. Note that in cygwin the ctrl-Z is not recognized as an EOF by gfortran; but ifort appears to recoginize it as a file separator on Linux platforms (on all platforms?) as an EOF with the ability to ontinue on. I have found the inconsistency to be an issue, and had to use the ISO_C_Binding interface to use the C routines to get consist behavior when trying to "follow" a file being written to be other processes and for reliably reading from FIFO files (although some compilers did just what I wanted at the time). I never filed bug reports on these as they seemed specifically avoided by the standard , allowing the behavior to be processor dependent. Does anything think it should be forbidden to read a multi-file file as formatted I/o (which appears to be the case with gfortran, which does not seem to allow additional I/O ; but maybe it does if a backspace is used (?)). Or is the desire to be able to read further, either because you are readina a multi-file file (definitely a system=dependent creature) or a file still being updated by another process? Regardless of the error messages what are the capabilities missing that you need? I find not being able to read binary streams or pipes from stdin in a standard format FAR more irritating myself.

gah4

unread,
Jul 31, 2022, 1:17:42 AM7/31/22
to
On Saturday, July 30, 2022 at 3:19:39 PM UTC-7, John wrote:
> A number of environments support multi-file formats MSWindows uses ctrl-Z (the EOF character).

The ctrl-Z EOF character is from CP/M days, and for some reason is still around.

The CP/M file system only keeps track of how many blocks are in a file.
For text files, there is ctrl-Z at the end, so it knows the exact end.

For not very good reasons, this lasted into MS-DOS, even though it does keep
track of file length in bytes.

In MS-DOS 3.2 days, I used to do bitmap image printing on EPSON and HP
printers, which means printing non-ASCII data. The MS-DOS print spooler
would end on ctrl-Z, so I had to keep those out of the file. A few other
characters it would do funny things with.

Dave Tholen

unread,
Aug 13, 2022, 12:00:23 AM8/13/22
to
>>>>>> If you read (sequentially) past the end-of-file, gfortran sets the value
>>>>>> of IOSTAT to -1, but if you read a second time, gfortran sets the value
>>>>>> of IOSTAT to 5001. I discovered this situation after having written a
>>>>>> program expecting subsequent READs to all return a negative number, and
>>>>>> of course the program didn't behave as expected until I investigated the
>>>>>> problem. So I'm curious as to why the choice was made to have IOSTAT
>>>>>> set to something other than -1 on any READ attempt after the end-of-file
>>>>>> condition has been triggered. Isn't the file pointer still just beyond
>>>>>> the last record in the file, even after the first failed READ?

>>>>> You are expected to test for IOSTAT and deal with the end-of-file condition.
>>>>> You are not expected to continue reading the file.

>>>> I actually do test for IOSTAT and deal with the end-of-file condition by
>>>> exiting the DO loop with the READ statement. But once the DO loop has
>>>> been exited, the program is in an outer DO loop, which can also read the
>>>> file.

>>> You need to fix the logic.

>> Apparently I haven't been clear.
>> The program has already been fixed.

> It had NOT been fixed when you wrote the first paragraph above.

On the contrary, the problem was identified and the code modified to deal
with the processor dependency BEFORE I had even started this thread. Of
course, I've said that before. Why do you insist on repeating the same
false claims?

> You wrote: "But once the DO loop has been exited, the program is in
> an outer DO loop, which can also read the file."

And what I wrote is correct. It's still correct, as one loop reads data
and the other loop reads metadata. Of course, I had already written that
as well.

>>>>> The closest anyone has come is Steve Lionel, who said he could
>>>>> make an argument for the second instance not being -1, but he didn't
>>>>> present that argument. That ifort returns -1 upon a second READ
>>>>> demonstrates that the situation is "processor dependent".

> The situation is NOT "processor dependent". The actual numerical value
> is processor dependent", but the sign of the value is NOT. The sign
> is required to be positive. ifort is not standard-conforming.

The sign is required to be positive for error conditions. From reading
the entire thread, it is quite clearly debatable whether reading past
the end of the file more than once is an end-of-file condition or an
error condition. It's situations like this one that often trigger an
"interpretation" of the standard by the standards committee. Maybe
some future standard will clarify the situation. That you fall on one
side of the debate does not mean there are not others on the other side
of the debate. The way I've interpreted the responses from others is
that the presence of a single physical end-of-file marker such as Ctrl-Z
could allow the file pointer to be positioned after the end of the file,
but BEFORE the end-of-file marker, such that a subsequent READ would
cause the reading of the end-of-file marker and trigger the end-of-file
condition, after which the file pointer would be positioned AFTER the
end-of-file marker, and then yet another READ would trigger an error
condition. But if there is no end-of-file marker, then the file pointer
could not be positioned any farther than the end of the file, such that
it remains in the same place no matter how many attempts are made to
READ beyond it. One such READ would look like any other such READ.

>> You wrote "the" standard as if there has been only one.

> There have been a number of standards published.

Glad you agree. Now, try to prove your claim that I haven't read the
standard.

> All say the same thing about IOSTAT since the keyword
> was introduced in FORTRAN 77 -- in regard to the
> value returned for no errors (zero), end of file (a negative
> value) and an error (a positive value).

You seem to be having trouble identifying what the issue is here. No
one is questioning whether positive is for errors and negative is for
end-of-file conditions. The issue is whether multiple reads past the
end of file are all end-of-file conditions or only the first is an
end-of-file condition.

>> In reality, there
>> have been multiple Fortran standards. I have a hardcopy of one of the
>> earlier standards and have read it. I have reference manuals to multiple
>> more recent compilers and I have read them as well. Since you do not know
>> the standard to which my program was written, and you also don't know which
>> of the standards or reference manuals I have read, you're not in a position
>> to make the claim that you did.

> What you say is irrelevant with regard to IOSTAT.

What I said *is* relevant to your claim that I haven't read the standard.

>>>>> My program *WAS* incompatible with gfortran's
>>>>> handling of a second end-of-file READ.

>>>> No, your program was wrong.

>>> Looks like you've finally admitted (tacitly) that you had your tenses wrong.
>>> Given that the different compilers return IOSTAT values with different signs
>>> for the same second end-of-file READ, it can be argued that the situation is
>>> "processor dependent".

>> All the IOSTAT values are processor-dependent (except for zero).
>> However, the value returned for end-of-file is negative.
>> The value for an error condition is positive.
>> This information is in the standard.

>> Irrelevant,

> It's very relevant, since you were testing for an IOSTAT value
> of the wrong sign.

On the contrary, I was testing for an IOSTAT value that indicates an
end-of-file condition. If you've reached the end of the file in one
read loop, one might expect that you've also reached the end of the
file in a different loop that reads the same file.

>>>> given that my program does not test for specific processor-dependent
>>>> values; rather, it tests for negative values. The outer DO loop's IOSTAT negative
>>>> value test has been superfluous since the program now exits the outer named DO loop
>>>> when the inner DO loop encounters the end-of-file condition.

>>>> Forty years ago, programs that OPENed a file and
>>>> started READing worked just fine with compilers that set the file pointer to
>>>> the beginning of the file, until they were moved to a BSD UNIX system whose
>>>> compiler, by default, OPENed a file with the pointer at the end of the file.
>>>> The program wasn't "wrong"; rather, it was incompatible with a processor
>>>> dependency.

>>> Your program was in error when you tried to read the file again,
>>> after receiving end-of-file notification.

>>> Rather, an error condition was triggered when the program tried to read
>>> the file again,

>>> And because your program contains an error, it is not standard conforming.

>> My program does not contain an error. The version that existed prior to me
>> even starting this thread contained an incompatibility with a gfortran
>> processor-dependent feature.

> Your program contained an error.

My program contained an incompatibility with a gfortran processor-dependent
feature.

> It first tested for a negative
> value indicating end-of-file, and then attempted to read another
> record that caused gfortran to return a positive value, indicating
> an error condition. Your program expected another negative value,

That's because my program expected that once the end of the file was
reached, it was still at the end of the file.

> instead of the positive vaue that was require by the Standard.

On the contrary, the standard requires a positive vaue [sic] for an
error condition. What we're dealing with here is a file pointer that
is past the last record of the file.

>>>>>> The current version is compatible with gfortran.

>>>>> but the code included a test on the value of IOSTAT to
>>>>> deal with the condition.

>>>>> That's why you received a positive number for IOSTAT when you tried
>>>>> to read the file after receiving end-of-file.

>>>> Yet ifort returns a negative number. Are you arguing that ifort is in
>>>> error?

>>> ifort is in error.

>> File a bug report for ifort,

> No, if you don't like it, you file a bug report with ifort.

I don't use ifort. You're the one who is claiming that it is in error,
not me. I have no proof that ifort is in error. As such, I have no
motivation to file a bug report.

>> if you think it is in error. Don't be surprised
>> if the response is that when you read past the end-of-file, it is an
>> end-of-file condition, regardless of the number of times you do it.

> You still have not read the standard.

You wrote "the" standard as if there has been only one. Of course, I've
said that already. What does the Robin Vowels standard say for how to
exit such an infinite loop condition?

> The Standard requires that
> a Fortran compiler to return a positive value when a program attempts
> to read past the end of file.

On the contrary, the standard requires that a Fortran compiler return a
negative value when a program attempts to read past the end of a file.

>> You still have not read the standard.

>>> You are still incorrect. There are all sorts of situations that the standard
>>> writers did not anticipate when the standards were written, hence the need for
>>> "interpretations" from the standards committee.

> There is no need for an "interpretation". The standard is clear and unequivocal.
> The standard has been around for 40 years.

Where does the standard clearly and unequivocally state that reading more
than once past the end of a file is *not* an end-of-file condition?

>>>>>> Find them with the help of debug options
>>>>>> such as subscript bound errors, substring errors, and the like.

>>>>> The WRITE statements showed that my subscripts are within bounds.

>>>> That's not the same as enabling subscript checks and all other checks.

>>> It is the same as checking for subscript bound errors.

> No it's not. You could have missed printing one critial value,
> or not realized that a subscript is out-of-range.

I stand by my statement that using a WRITE statement to display the values
of subscripts is the same as checking for subscript bound errors. As for
some other critial [sic] value, that's rather vague.

>> But your kind of error can be caused by many things besides
>> subscript errors.

>> My WRITE statements were not limited to the display of only subscript values.

> That's irrelevant.

On the contrary, it's quite relevant, especially given your claim that I
missed printing one critial [sic] value.

>> The use of WRITE statements to check on the values of variables has served
>> me well for debugging purposes for decades. However, when the addition of a
>> WRITE statement makes a problem go away, one wonders how that can happen.

> I repeat: your kind of error can be caused by many things
> besides subscript errors. You need to specify options that
> check for ALL errors, including subscript errors.

What's the option that checks for Robin Vowels errors?

gah4

unread,
Aug 13, 2022, 12:22:05 AM8/13/22
to
On Friday, August 12, 2022 at 9:00:23 PM UTC-7, Dave Tholen wrote:

(snip)

> The sign is required to be positive for error conditions. From reading
> the entire thread, it is quite clearly debatable whether reading past
> the end of the file more than once is an end-of-file condition or an
> error condition. It's situations like this one that often trigger an
> "interpretation" of the standard by the standards committee. Maybe
> some future standard will clarify the situation. That you fall on one
> side of the debate does not mean there are not others on the other side
> of the debate. The way I've interpreted the responses from others is
> that the presence of a single physical end-of-file marker such as Ctrl-Z
> could allow the file pointer to be positioned after the end of the file,
> but BEFORE the end-of-file marker, such that a subsequent READ would
> cause the reading of the end-of-file marker and trigger the end-of-file
> condition, after which the file pointer would be positioned AFTER the
> end-of-file marker, and then yet another READ would trigger an error
> condition. But if there is no end-of-file marker, then the file pointer
> could not be positioned any farther than the end of the file, such that
> it remains in the same place no matter how many attempts are made to
> READ beyond it. One such READ would look like any other such READ.

I guess so.

The description of "end of file record" allows for a physical or virtual
version. It mostly matters for BACKSPACE to work.

Much of the Fortran standard is written to allow for various actual
implementations over the years. And partly that comes from the
record oriented nature of Fortran I/O.

In C, once you get to EOF, you will keep getting one, unless the file
length increases while your program is running.

There are some complications in both Fortran and C when you do
both reading and writing on the same file.




Dave Tholen

unread,
Aug 13, 2022, 6:05:28 AM8/13/22
to
>>>> If I understand it right, you should test for not zero, and act accordingly.

>>>> It is negative for EOF, but positive for I/O errors, which most likely you
>>>> should also exit your loop, and/or handle appropriately.

>>> Not in this particular case. In older versions of the data file I'm
>>> processing, they used csv format to present dozens and dozens of
>>> quantities for each object in the database, and when a value wasn't
>>> available, they simply omitted it, leading to consecutive commas,
>>> and gfortran's list-directed READ statement handled it splendidly.
>>> However, in the latest version of the data file, a missing value is
>>> now represented as "null". For example, five values might be in
>>> this file as:
>>>
>>> 18,97.43,null,-4.31,102
>>>
>>> but attempting to read the characters "null" into an INTEGER or REAL
>>> variable triggers an I/O error.

> Characters are characters, and cannot be read into an integer or real variable.

Hence why I said it triggers an I/O error.

> An appropriate variable would be a CHARACTER variable, but then the
> characters NULL would need to be enclosed in apostrophes.

The data file does have some entries whose values are characters, and
they do enclose those in quotation marks, but not the null entries. I
preferred their previous approach of simply omitting them, leading to
consecutive commas.

> A better approach might be to read the entire line into a CHARACTER variable,
> and then to scan it for 'null, and then to delete the word. Finally read the
> altered line.

I implemented that long ago.

Dave Tholen

unread,
Aug 13, 2022, 6:11:01 AM8/13/22
to
>>>>> If I understand it right, you should test for not zero, and act accordingly.
>>>>> It is negative for EOF, but positive for I/O errors, which most likely you
>>>>> should also exit your loop, and/or handle appropriately.

>>>> Not in this particular case. In older versions of the data file I'm
>>>> processing, they used csv format to present dozens and dozens of
>>>> quantities for each object in the database, and when a value wasn't
>>>> available, they simply omitted it, leading to consecutive commas,
>>>> and gfortran's list-directed READ statement handled it splendidly.
>>>> However, in the latest version of the data file, a missing value is
>>>> now represented as "null". For example, five values might be in
>>>> this file as:
>>>> 18,97.43,null,-4.31,102
>>>> but attempting to read the characters "null" into an INTEGER or REAL
>>>> variable triggers an I/O error.

>> Characters are characters, and cannot be read into an integer or real variable.
>> An appropriate variable would be a CHARACTER variable, but then the
>> characters NULL would need to be enclosed in apostrophes.
>> A better approach might be to read the entire line into a CHARACTER variable,
>> and then to scan it for 'null, and then to delete the word.  Finally read the
>> altered line.

> If each READ statement is definitely reading one and only one line, then reading each line into a character variable, deleting each
> instance of the word 'null', and then reading data from the character variable seems like the easiest solution by far.

And that's what I had implemented months ago. That DO loop exited when the INDEX
function returned a zero value. I'm just glad that modern hardware and compilers
allow for CHARACTER variables at least 2000 characters long.


Dave Tholen

unread,
Aug 13, 2022, 6:39:06 AM8/13/22
to
>> If each READ statement is definitely reading one and only one line, then
>> reading each line into a character variable, deleting each instance of
>> the word 'null', and then reading data from the character variable seems
>> like the easiest solution by far.
>
> I would find it easy enough to preprocess the file, such as:
>
> sed "s/null//" < infile > outfile

Fine if you're on a UNIX machine. I haven't investigated whether there
is a sed for Windows. But the downside is doubling the storage
requirement. The entire collection of 3000+ data files consumes almost
2 TB as is. The program to read everything and process it took almost
three days to run. Or six days if you count the instance that was a few
hours from finishing when Windows Update decided to reboot the system.
(Insert rant about Windows Update being too stupid to know when a
number cruncher is running and to defer the reboot. Don't bother to
tell me about how the user can postpone the update procedure. I have
one machine for which automatic updates has been disabled, and it nags
every day to install the Windows Defender Security Intelligence Update.)

> Or maybe the generating program has an option to change this.

I have no control over the generating program.

> But yes, as a Fortran solution, reading line by line and processing the
> line is often fine, too.
>
> Many years ago (Fortran 77 days), I was reading a file something like:
>
> READ(5,*, END=999) (X(I), Y(I), I=1,999)
>
> and expecting the data to be read, and I to be 1 more than the pairs read.
> That was before I saw a copy of the standard, and only had the DEC manuals.
>
> I even had the DEC bug report form, before learning that the standard,
> and especially the DEC compilers, didn't require that.
>
> In the case of either EOF or I/O error, what is actually stored, or the value
> of implied-DO variables, is undefined.
>
> For my problem, a normal (not implied) DO fixed it, but others are
> not so easy to fix.

That's not one I've run into, but yeah, I can see why one might expect
I to be 1 more than the pairs read. Expectations are where one can run
afoul of the standard, especially if those expectations were developed
while working with a different programming language. In the present
case, I suspect the changes made to the data files I've been processing
were influenced by python users.

Robin Vowels

unread,
Aug 15, 2022, 5:45:29 AM8/15/22
to
On Sunday, July 17, 2022 at 8:13:50 PM UTC+10, Dave Tholen wrote:
> >>> On a completely separate matter, I have a different program that
> >>> didn't behave as expected, and that misbehavior was totally repeatable.
> >>> In an attempt to debug the program, I added a WRITE statement to check
> >>> on the value of a variable during execution. However, once the WRITE
> >>> statement was added, the program started behaving properly, repeatably.
> >>> Comment out the added WRITE statement, and the program once again
> >>> misbehaves, repeatedly. Re-enable the WRITE statement, and everything
> >>> is once again hunky-dory. Damned frustrating. It's too easy to blame
> >>> the optimizer. Anybody have any generic advice on what to look for in
> >>> such a situation?
>
> >> Remove the write statement and compile with -Wall -fcheck=all. This
> >> might find where you are stomping on memory.
>
> > I would add -Werror. If you always compile without warnings, your life will be simpler.
> Oh, that's a deadly option for me. I use A LOT of implicit type conversion,
> such as doing a calculation internally using double precision, but saving
> the result in single precision, such as
>
> snglz = dblex * dbley
>
> -Werror is happy if an explicit REAL() is used. For the single precision
> version of the real component of a double complex number, one needs to use
> REAL(REAL(dblecmplx)) to make -Werror happy.
.
REAL (dblecmplx, kind=1.0)
should be sufficient.

Robin Vowels

unread,
Aug 15, 2022, 5:52:13 AM8/15/22
to
On Monday, July 18, 2022 at 12:02:53 AM UTC+10, Dave Tholen wrote:
> >> So, you're saying that if my program has subprograms A, B, C, D, and E,
> >> and the crash occurs while it's executing subprogram C, the apparent
> >> overwriting could be in A, B, D, or E?
.
> > The error could be in any of A, B, C, D, E, and/or the main program.
.
> Can you provide an example?
.
You already have a program that contains this kind of error.

Robin Vowels

unread,
Aug 15, 2022, 6:01:49 AM8/15/22
to
On Monday, July 18, 2022 at 9:57:56 AM UTC+10, Dave Tholen wrote:
> >> Can you provide an example?
> > If your interest is in gaining some insight and answers as opposed to an open-ended discussion, you may also want to post at the Fortran Discourse site:
> > https://fortran-lang.discourse.group/
> Are you suggesting that fortran-lang.discourse.group is for insight and that
> comp.lang.fortran is for open-ended discussions?
> > And consider posting there first *your own small example* that illustrates what you are doing in your code.
.
> You're assuming that the problem can be reproduced with a "small example".
> The program isn't small. If the simple addition of a WRITE statement can
> trigger correct behavior, shrinking of the task to a "small example" will
> lead to massive changes that more than likely will also eliminate the bug,
> especially if the bug is NOT in the subprogram where the crash occurs.
.
You have already been told that the bug could be in any of your
subroutines, functions, and main program.
.
Start work on that.

Robin Vowels

unread,
Aug 15, 2022, 6:14:36 AM8/15/22
to
On Wednesday, July 20, 2022 at 9:00:10 PM UTC+10, Dave Tholen wrote:
> >>>>>>>>>> If you read (sequentially) past the end-of-file, gfortran sets the value
> >>>>>>>>>> of IOSTAT to -1, but if you read a second time, gfortran sets the value
> >>>>>>>>>> of IOSTAT to 5001. I discovered this situation after having written a
> >>>>>>>>>> program expecting subsequent READs to all return a negative number, and
> >>>>>>>>>> of course the program didn't behave as expected until I investigated the
> >>>>>>>>>> problem. So I'm curious as to why the choice was made to have IOSTAT
> >>>>>>>>>> set to something other than -1 on any READ attempt after the end-of-file
> >>>>>>>>>> condition has been triggered. Isn't the file pointer still just beyond
> >>>>>>>>>> the last record in the file, even after the first failed READ?
>
> >>>>>>>>> You are expected to test for IOSTAT and deal with the end-of-file condition.
> >>>>>>>>> You are not expected to continue reading the file.
>
> >>>>>>>> I actually do test for IOSTAT and deal with the end-of-file condition by
> >>>>>>>> exiting the DO loop with the READ statement. But once the DO loop has
> >>>>>>>> been exited, the program is in an outer DO loop, which can also read the
> >>>>>>>> file.
>
> >>>>>>> You need to fix the logic.
>
> >>>>>> Apparently I haven't been clear.
> >>>>>> The program has already been fixed.
>
> >>>>> But it hasn't been fixed.
>
> >>>> Incorrect; reread my previous statement.
>
> >>>>> You admitted it.
>
> >>>> Incorrect.
>
> >>>>> You said that after detecting end of file using IOSTAT, you exited the loop,
> >>>>> and the outer loop then proceeded to execute READs on the same file.
>
> >>>> That was before the fix. Now it is using a named DO loop, and when
> >>>> the data-reading DO loop encounters the end-of-file condition, it
> >>>> exits the outer DO loop, so the outer DO loop's READ statement is
> >>>> not encountered. That made the value of IOSTAT in the outer DO loop
> >>>> irrelevant. However, that I succeeded in making my program work
> >>>> properly did not change my curiosity as to why the value of IOSTAT
> >>>> changed upon the second end-of-file READ.
>
> >>>>>> It was fixed before I even posted on this forum. The question is not
> >>>>>> how to fix the problem. The question is why the value of IOSTAT was
> >>>>>> changed.
>
> >>>>> That has already been explained to you.
>
> >>>> Where? The closest anyone has come is Steve Lionel, who said he could
> >>>> make an argument for the second instance not being -1, but he didn't
> >>>> present that argument. That ifort returns -1 upon a second READ
> >>>> demonstrates that the situation is "processor dependent".
>
> >>>>>> There must be some rationale.
>
> >>>>>>>> It also tests IOSTAT to deal with the end-of-file condition,
>
> >>>>>>> The program has already hit the end of file.
> >>>>>>> Now you are trying to read read the same file at the same place.
>
> >>>>>> That's just it: same file, same place, same action, yet a different
> >>>>>> IOSTAT result. Not what I had expected.
>
> >>>>> Again, that has been explained to you.
>
> >>>> Again, where?
>
> >>>>>>>> but
> >>>>>>>> it tested for a negative number, which IOSTAT was no longer set to.
>
> >>>>>>> You need to avoid reading after end of file has been detected.
>
> >>>>>> Why? IOSTAT was added so that a program could handle error conditions.
> >>> IOSTAT was added so that end-of-file could be detected and dealt with.
> >>> IOSTAT was also added so that error conditions could be detected.
> >>> [Note that end-of-file is not considered to be an error condition.]
>
> >> But another READ past the end-of-file apparently is considered to be an
> >> error condition by gfortran, whereas ifort apparently considers it to be
> >> an end-of-file condition.
>
> >>>>> Provided that you deal with the condition and do not do silly things like reading
> >>>>> the same file again, after detecting end-of file.
>
> >>>> Hardly silly, given that reading the same file again just triggers yet another
> >>>> error condition,
>
> >>> No it doesn't. Reading the same file again after end of file has been detected
> >>> is the first error condition raised.
>
> >> You don't know that. In fact, if you read elsewhere in this thread, you'd
> >> know that the data file uses the characters "null" in place of a missing
> >> numerical value, which triggers multiple error conditions long before a
> >> second end-of-file READ occurs. It's hardly the first error condition
> >> raised.
>
> >>> IOSTAT returns a negative value for end of file.
> >>> IOSTAT returns a positive integer for an error condition.
>
> >> Yet ifort returns -1 for a second end-of-file READ while gfortran returns
> >> 5001. Are you arguing that one of the two compilers is not standard
> >> compliant?
>
> >>>> and IOSTAT was designed to allow programs to deal with the
> >>>> error condition.
>
> >>>>>> My program was designed to deal with the error condition. Had gfortran
> >>>>>> consistently returned a negative IOSTAT for every attempt to READ past
> >>>>>> the end-of-file, my program would have worked exactly as intended.
>
> >>>>> Listen up. Your program is in error. Fix it.
>
> >>>> Listen up: you are incorrect.
>
> >>> I am not incorrect. Read the standard.
>
> >> You are incorrect. My program is standard-conforming and works properly.
>
> > Since you have not read the standard, you do not know whether your program
> > is "standard conforming".
> You wrote "the" standard as if there has been only one. In reality, there
> have been multiple Fortran standards. I have a hardcopy of one of the
> earlier standards and have read it. I have reference manuals to multiple
> more recent compilers and I have read them as well. Since you do not know
> the standard to which my program was written, and you also don't know which
> of the standards or reference manuals I have read, you're not in a position
> to make the claim that you did.
> >>>> My program *WAS* incompatible with gfortran's
> >>>> handling of a second end-of-file READ.
>
> >>> No, your program was wrong.
>
> >> Looks like you've finally admitted (tacitly) that you had your tenses wrong.
> >> Given that the different compilers return IOSTAT values with different signs
> >> for the same second end-of-file READ, it can be argued that the situation is
> >> "processor dependent".
>
> > All the IOSTAT values are processor-dependent (except for zero).
> > However, the value returned for end-of-file is negative.
> > The value for an error condition is positive.
> > This information is in the standard.
> Irrelevant, given that my program does not test for specific processor-dependent
> values; rather, it tests for negative values. The outer DO loop's IOSTAT negative
> value test has been superfluous since the program now exits the outer named DO loop
> when the inner DO loop encounters the end-of-file condition.
> >> Forty years ago, programs that OPENed a file and
> >> started READing worked just fine with compilers that set the file pointer to
> >> the beginning of the file, until they were moved to a BSD UNIX system whose
> >> compiler, by default, OPENed a file with the pointer at the end of the file.
> >> The program wasn't "wrong"; rather, it was incompatible with a processor
> >> dependency.
>
> >>> Your program was in error when you tried to read the file again,
> >>> after receiving end-of-file notification.
>
> >> Rather, an error condition was triggered when the program tried to read
> >> the file again,
>
> > And because your program contains an error, it is not standard conforming.
> My program does not contain an error. The version that existed prior to me
> even starting this thread contained an incompatibility with a gfortran
> processor-dependent feature.
.
The feature in question is NOT a processor-dependent feature.
Your program tested for a negative value when it should have tested for a positive value.
Your program was wrong.

Dave Tholen

unread,
Aug 15, 2022, 6:14:57 AM8/15/22
to
>>>> So, you're saying that if my program has subprograms A, B, C, D, and E,
>>>> and the crash occurs while it's executing subprogram C, the apparent
>>>> overwriting could be in A, B, D, or E?

>>> The error could be in any of A, B, C, D, E, and/or the main program.

>> Can you provide an example?

> You already have a program that contains this kind of error.

Not a useful example. A useful example would be a program that has an
*identified* bug in A but crashes while executing C, except when a WRITE
statement has been added to C to check on subscript bounds. That way, a
programmer could fix the bug in A and verify that the crash in C no longer
occurs, even without the WRITE statement.

Dave Tholen

unread,
Aug 15, 2022, 6:29:42 AM8/15/22
to
>>>> Can you provide an example?

>>> If your interest is in gaining some insight and answers as opposed to an open-ended discussion, you may also want to post at the Fortran Discourse site:
>>> https://fortran-lang.discourse.group/

>> Are you suggesting that fortran-lang.discourse.group is for insight and that
>> comp.lang.fortran is for open-ended discussions?

>>> And consider posting there first *your own small example* that illustrates what you are doing in your code.

>> You're assuming that the problem can be reproduced with a "small example".
>> The program isn't small. If the simple addition of a WRITE statement can
>> trigger correct behavior, shrinking of the task to a "small example" will
>> lead to massive changes that more than likely will also eliminate the bug,
>> especially if the bug is NOT in the subprogram where the crash occurs.

> You have already been told that the bug could be in any of your
> subroutines, functions, and main program.

Irrelevant here, as the suggestion was to shrink the program to a small
example. Such shrinkage could easily eliminate the alleged bug.

> Start work on that.

I had already started work on that, namely with the WRITE statements to check
on the values of relevant variables, but that made the problem go away. That
raised the question of where next to look, given that looking at the subroutine
in which the crash occurred was fruitless. The question in this thread was for
some generic guidance as to where might be a more fruitful place to look. The
best you've been able to come up with is "look everywhere". At least others
have recommended specific compiler options, which is far more useful.

Robin Vowels

unread,
Aug 15, 2022, 6:54:54 AM8/15/22
to
On Monday, August 15, 2022 at 8:14:57 PM UTC+10, Dave Tholen wrote:
> >>>> So, you're saying that if my program has subprograms A, B, C, D, and E,
> >>>> and the crash occurs while it's executing subprogram C, the apparent
> >>>> overwriting could be in A, B, D, or E?
> >>> The error could be in any of A, B, C, D, E, and/or the main program.
> >> Can you provide an example?
.
> > You already have a program that contains this kind of error.
.
> Not a useful example.
.
It's the only one that you have.

Robin Vowels

unread,
Aug 15, 2022, 7:02:17 AM8/15/22
to
On Monday, August 15, 2022 at 8:29:42 PM UTC+10, Dave Tholen wrote:
> >>>> Can you provide an example?
>
> >>> If your interest is in gaining some insight and answers as opposed to an open-ended discussion, you may also want to post at the Fortran Discourse site:
> >>> https://fortran-lang.discourse.group/
>
> >> Are you suggesting that fortran-lang.discourse.group is for insight and that
> >> comp.lang.fortran is for open-ended discussions?
>
> >>> And consider posting there first *your own small example* that illustrates what you are doing in your code.
> >> You're assuming that the problem can be reproduced with a "small example".
> >> The program isn't small. If the simple addition of a WRITE statement can
> >> trigger correct behavior, shrinking of the task to a "small example" will
> >> lead to massive changes that more than likely will also eliminate the bug,
> >> especially if the bug is NOT in the subprogram where the crash occurs.
> > You have already been told that the bug could be in any of your
> > subroutines, functions, and main program.
.
> Irrelevant here,
.
It's not irrelevant.
.
Are you really trying to find the bug?
All you seem to be doing is arguing about it.
.
>as the suggestion was to shrink the program to a small
> example. Such shrinkage could easily eliminate the alleged bug.
>
> > Start work on that.
>
> I had already started work on that, namely with the WRITE statements to check
> on the values of relevant variables, but that made the problem go away.
.
That is what you wrote in your first post.
You need to do what we have suggested. Turn on all checks.
.
> That
> raised the question of where next to look, given that looking at the subroutine
> in which the crash occurred was fruitless. The question in this thread was for
> some generic guidance as to where might be a more fruitful place to look. The
> best you've been able to come up with is "look everywhere".
.
A long time ago, I suggested truning on subscript checks and all other debug
options.
.
> At least others
> have recommended specific compiler options, which is far more useful.
.
They have suggested the same as I did.

Thomas Koenig

unread,
Aug 15, 2022, 7:04:44 AM8/15/22
to
Dave Tholen <tho...@antispam.ham> schrieb:
>>>>> Can you provide an example?
>
>>>> If your interest is in gaining some insight and answers as opposed to an open-ended discussion, you may also want to post at the Fortran Discourse site:
>>>> https://fortran-lang.discourse.group/
>
>>> Are you suggesting that fortran-lang.discourse.group is for insight and that
>>> comp.lang.fortran is for open-ended discussions?
>
>>>> And consider posting there first *your own small example* that illustrates what you are doing in your code.
>
>>> You're assuming that the problem can be reproduced with a "small example".
>>> The program isn't small. If the simple addition of a WRITE statement can
>>> trigger correct behavior, shrinking of the task to a "small example" will
>>> lead to massive changes that more than likely will also eliminate the bug,
>>> especially if the bug is NOT in the subprogram where the crash occurs.
>
>> You have already been told that the bug could be in any of your
>> subroutines, functions, and main program.
>
> Irrelevant here, as the suggestion was to shrink the program to a small
> example. Such shrinkage could easily eliminate the alleged bug.

In that case, I would recommend using valgrind (if -fcheck=all or
equivalent does not help).

Robin Vowels

unread,
Aug 15, 2022, 7:48:04 AM8/15/22
to
On Saturday, August 13, 2022 at 2:00:23 PM UTC+10, Dave Tholen wrote:

> > It had NOT been fixed when you wrote the first paragraph above.
> On the contrary, the problem was identified and the code modified to deal
> with the processor dependency BEFORE I had even started this thread. Of
> course, I've said that before. Why do you insist on repeating the same
> false claims?
> > You wrote: "But once the DO loop has been exited, the program is in
> > an outer DO loop, which can also read the file."
> And what I wrote is correct. It's still correct, as one loop reads data
> and the other loop reads metadata. Of course, I had already written that
> as well.
> >>>>> The closest anyone has come is Steve Lionel, who said he could
> >>>>> make an argument for the second instance not being -1, but he didn't
> >>>>> present that argument. That ifort returns -1 upon a second READ
> >>>>> demonstrates that the situation is "processor dependent".
>
> > The situation is NOT "processor dependent". The actual numerical value
> > is processor dependent", but the sign of the value is NOT. The sign
> > is required to be positive. ifort is not standard-conforming.
>
> The sign is required to be positive for error conditions. From reading
> the entire thread, it is quite clearly debatable whether reading past
> the end of the file more than once is an end-of-file condition
>
The standard is clear and unequivocal. I quoted it in this thread.
The last record has been read. Reading again returns a negative
value in IOSTAT, indicating end-of-file.
Reading again is an error, and IOSTAT yields a positive value,
indicating an error.
>
> or an
> error condition. It's situations like this one that often trigger an
> "interpretation" of the standard by the standards committee.
>
You are in fairy land.
The standard of 1977 introduced IOSTAT and specified what happens.
That hasn't changed since.
In 44 years there has not been "clarification" because none was needed.
>
Read the standard, and move on.
>
> Maybe
> some future standard will clarify the situation. That you fall on one
> side of the debate does not mean there are not others on the other side
> of the debate. The way I've interpreted the responses from others is
> that the presence of a single physical end-of-file marker such as Ctrl-Z
> could allow the file pointer to be positioned after the end of the file,
> but BEFORE the end-of-file marker, such that a subsequent READ would
> cause the reading of the end-of-file marker and trigger the end-of-file
> condition, after which the file pointer would be positioned AFTER the
> end-of-file marker, and then yet another READ would trigger an error
> condition. But if there is no end-of-file marker, then the file pointer
> could not be positioned any farther than the end of the file, such that
> it remains in the same place no matter how many attempts are made to
> READ beyond it. One such READ would look like any other such READ.
> >> You wrote "the" standard as if there has been only one.
>
> > There have been a number of standards published.
> Glad you agree. Now, try to prove your claim that I haven't read the
> standard.
You haven't read the relevant standard,
or you wouldn't be still arguing about fanciful possibilities.
>
> > All say the same thing about IOSTAT since the keyword
> > was introduced in FORTRAN 77 -- in regard to the
> > value returned for no errors (zero), end of file (a negative
> > value) and an error (a positive value).
> You seem to be having trouble identifying what the issue is here. No
> one is questioning whether positive is for errors and negative is for
> end-of-file conditions. The issue is whether multiple reads past the
> end of file are all end-of-file conditions or only the first is an
> end-of-file condition.
>
Listen up. It is an error to try to read the file after you have already received
an end-of-file.
You get an ERROR indication via IOSTAT..
If you keep ignoring the error condition, your program can get into a loop.
>
> >> In reality, there
> >> have been multiple Fortran standards. I have a hardcopy of one of the
> >> earlier standards and have read it.
>
Which one is that?

Dave Tholen

unread,
Aug 22, 2022, 7:31:52 PM8/22/22
to
>>>>>> So, you're saying that if my program has subprograms A, B, C, D, and E,
>>>>>> and the crash occurs while it's executing subprogram C, the apparent
>>>>>> overwriting could be in A, B, D, or E?

>>>>> The error could be in any of A, B, C, D, E, and/or the main program.

>>>> Can you provide an example?

>>> You already have a program that contains this kind of error.

>> Not a useful example.

> It's the only one that you have.

That's because you failed to provide one when I asked you to do so.

Dave Tholen

unread,
Aug 22, 2022, 8:02:28 PM8/22/22
to
>>>>>> Can you provide an example?

>>>>> If your interest is in gaining some insight and answers as opposed to an open-ended discussion, you may also want to post at the Fortran Discourse site:
>>>>> https://fortran-lang.discourse.group/

>>>> Are you suggesting that fortran-lang.discourse.group is for insight and that
>>>> comp.lang.fortran is for open-ended discussions?

>>>>> And consider posting there first *your own small example* that illustrates what you are doing in your code.

>>>> You're assuming that the problem can be reproduced with a "small example".
>>>> The program isn't small. If the simple addition of a WRITE statement can
>>>> trigger correct behavior, shrinking of the task to a "small example" will
>>>> lead to massive changes that more than likely will also eliminate the bug,
>>>> especially if the bug is NOT in the subprogram where the crash occurs.

>>> You have already been told that the bug could be in any of your
>>> subroutines, functions, and main program.

>> Irrelevant here,

> It's not irrelevant.

On the contrary, it is irrelevant, for the reason stated. I'll note that you
didn't provide any response to that reason, which is still intact a few lines
below, set off by newly added dashes.

> Are you really trying to find the bug?

When I have the time to do so. The problem hasn't occurred in any recent
use of the program, so it hasn't been a priority.

> All you seem to be doing is arguing about it.

What seems to you is also irrelevant. Surely you must know that it takes
two to argue. Who might that other arguer seem to be to you?

------------------------------------------------------------------
>> as the suggestion was to shrink the program to a small
>> example. Such shrinkage could easily eliminate the alleged bug.
------------------------------------------------------------------

>>> Start work on that.

>> I had already started work on that, namely with the WRITE statements to check
>> on the values of relevant variables, but that made the problem go away.

> That is what you wrote in your first post.

Reading comprehension makes a cameo appearance. Why have you had such
trouble understanding the rest of what I wrote in my first post?

> You need to do what we have suggested. Turn on all checks.

"We"? Others have made specific suggestions, while the best you could do
was to suggest looking everywhere.

>> That
>> raised the question of where next to look, given that looking at the subroutine
>> in which the crash occurred was fruitless. The question in this thread was for
>> some generic guidance as to where might be a more fruitful place to look. The
>> best you've been able to come up with is "look everywhere".

> A long time ago, I suggested truning on subscript checks and all other debug
> options.

"All other debug options" implicitly assumes that one knows about all the
available debug options. However, Koenig suggested using the -fsanitize option,
which isn't even listed among the "options specific to GNU Fortran" listed at
https://gcc.gnu.org/onlinedocs/gcc-4.9.2/gfortran/Option-Summary.html#Option-Summary
Instead, one can find it among the GCC "Program Instrumentation Options", which
doesn't sound like a "debug option".

>> At least others
>> have recommended specific compiler options, which is far more useful.

> They have suggested the same as I did.

Are you seriously trying to suggest that your contributions to this thread are
the same as what others have contributed?

Dave Tholen

unread,
Aug 22, 2022, 8:30:49 PM8/22/22
to
>>> It had NOT been fixed when you wrote the first paragraph above.

>> On the contrary, the problem was identified and the code modified to deal
>> with the processor dependency BEFORE I had even started this thread. Of
>> course, I've said that before. Why do you insist on repeating the same
>> false claims?

>>> You wrote: "But once the DO loop has been exited, the program is in
>>> an outer DO loop, which can also read the file."

>> And what I wrote is correct. It's still correct, as one loop reads data
>> and the other loop reads metadata. Of course, I had already written that
>> as well.

>>>>>>> The closest anyone has come is Steve Lionel, who said he could
>>>>>>> make an argument for the second instance not being -1, but he didn't
>>>>>>> present that argument. That ifort returns -1 upon a second READ
>>>>>>> demonstrates that the situation is "processor dependent".

>>> The situation is NOT "processor dependent". The actual numerical value
>>> is processor dependent", but the sign of the value is NOT. The sign
>>> is required to be positive. ifort is not standard-conforming.

>> The sign is required to be positive for error conditions. From reading
>> the entire thread, it is quite clearly debatable whether reading past
>> the end of the file more than once is an end-of-file condition

> The standard is clear and unequivocal. I quoted it in this thread.

So has Robert Corbett:

"Subclause 12.11.1 of the Fortran 2018 standard states

The set of input/output error conditions is
processor dependent."

Gee, I've been saying repeatedly that the situation is processor
dependent, while you claimed (several lines above) "The situation
is NOT 'processor dependent'". Looks like the 2018 standard agrees
with me.

> The last record has been read. Reading again returns a negative
> value in IOSTAT, indicating end-of-file.
> Reading again is an error, and IOSTAT yields a positive value,
> indicating an error.

Hello??? I wrote in my original post that the IOSTAT value is 5001
when the second READ is attempted, so all you just did was to repeat
what I've known from the beginning of this thread.

>> or an
>> error condition. It's situations like this one that often trigger an
>> "interpretation" of the standard by the standards committee.

> You are in fairy land.

Are you seriously trying to suggest that the Fortran standards have
all been written so well that no interpretations have ever been issued
by the standards committee?

> The standard of 1977 introduced IOSTAT and specified what happens.
> That hasn't changed since.
> In 44 years there has not been "clarification" because none was needed.

You need to read the contributions of others in this thread. All sorts
of "clarifications" have been made. At the risk of repetition:

"Subclause 12.11.1 of the Fortran 2018 standard states

The set of input/output error conditions is
processor dependent."

> Read the standard, and move on.

Follow your own advice.

>> Maybe
>> some future standard will clarify the situation. That you fall on one
>> side of the debate does not mean there are not others on the other side
>> of the debate. The way I've interpreted the responses from others is
>> that the presence of a single physical end-of-file marker such as Ctrl-Z
>> could allow the file pointer to be positioned after the end of the file,
>> but BEFORE the end-of-file marker, such that a subsequent READ would
>> cause the reading of the end-of-file marker and trigger the end-of-file
>> condition, after which the file pointer would be positioned AFTER the
>> end-of-file marker, and then yet another READ would trigger an error
>> condition. But if there is no end-of-file marker, then the file pointer
>> could not be positioned any farther than the end of the file, such that
>> it remains in the same place no matter how many attempts are made to
>> READ beyond it. One such READ would look like any other such READ.

>>>> You wrote "the" standard as if there has been only one.

>>> There have been a number of standards published.

>> Glad you agree. Now, try to prove your claim that I haven't read the
>> standard.

> You haven't read the relevant standard,
> or you wouldn't be still arguing about fanciful possibilities.

How would you know what the relevant standard is? Was my program written
to the Fortran 2003 standard? Or was it written to the Fortran 95 standard?
Or maybe the Fortran 90 standard? Perhaps even the Fortran 77 standard?

>>> All say the same thing about IOSTAT since the keyword
>>> was introduced in FORTRAN 77 -- in regard to the
>>> value returned for no errors (zero), end of file (a negative
>>> value) and an error (a positive value).

>> You seem to be having trouble identifying what the issue is here. No
>> one is questioning whether positive is for errors and negative is for
>> end-of-file conditions. The issue is whether multiple reads past the
>> end of file are all end-of-file conditions or only the first is an
>> end-of-file condition.

> Listen up. It is an error to try to read the file after you have already received
> an end-of-file.

Listen up. I wrote in the original post that the IOSTAT value is 5001 after
an end-of-file has been encountered, hence I've known from the beginning of
this thread that gfortran treated it as an error condition. Why do you keep
repeating what has been noted from the beginning of this thread?

> You get an ERROR indication via IOSTAT..
> If you keep ignoring the error condition, your program can get into a loop.

Irrelevant, given that my program doesn't keep ignoring the error condition.
>>>> In reality, there
>>>> have been multiple Fortran standards. I have a hardcopy of one of the
>>>> earlier standards and have read it.

> Which one is that?

The relevant one.

Dave Tholen

unread,
Aug 22, 2022, 8:41:50 PM8/22/22
to
> The feature in question is NOT a processor-dependent feature.

Then explain why the 2018 standard states that "The set of input/output error
conditions is processor dependent."

> Your program tested for a negative value when it should have tested for a positive value.
> Your program was wrong.

The program was incompatible with gfortran, but has been compatible with
gfortran since before I even started this thread. You seem to have a fetish
regarding programming issues that no longer exist.

Louis Krupp

unread,
Aug 23, 2022, 1:34:59 AM8/23/22
to
On 8/22/2022 6:02 PM, Dave Tholen wrote:

<snip>

>> Are you really trying to find the bug?
>
> When I have the time to do so.  The problem hasn't occurred in any recent
> use of the program, so it hasn't been a priority.
>

I can see some risk in that approach. While you're not seeing the bug's
most obvious manifestation, you don't know if it's dropping a random
value in a random place in memory. That can be harmless ... until it's not.

It sounded, at least when you first posted, like you had a mysterious
bug that you could reproduce. There are maintenance programmers out
there who would be thrilled to work on a bug like that. It offers a
challenge and an unknown payback: Going into it, you don't know what's
not going to go wrong once the bug is fixed.

When I was working, I lived for bugs like this. I'd come in to the
office late and I'd sit there with a cup of tea and a chocolate bar and
Bruckner's 7th Symphony on my boombox and I'd crank up the volume and
there was nobody around to complain and I'd lose track of time and once
in a while I'd walk around and see if the sun was up (management didn't
usually give window offices to people who liked to work at night) and by
the time the normal people rolled in around 8:00 AM I'd at least have a
handle on what was going wrong and I could share the details with
colleagues who were interested and a few who weren't and then I'd go
home and try to get some rest, secure in the knowledge that I'd done my
bit and that if nobody saw me again until the next day they wouldn't
miss me because have you ever actually listened to Bruckner?

Louis




Robin Vowels

unread,
Aug 23, 2022, 1:18:11 PM8/23/22
to
On Tuesday, August 23, 2022 at 10:02:28 AM UTC+10, Dave Tholen wrote:
.
> > Are you really trying to find the bug?
.
> When I have the time to do so. The problem hasn't occurred in any recent
> use of the program, so it hasn't been a priority.
.
Your particular complaint was that the program failed when a
print statement is inserted in it.
The error is still there.
.
As such an error is typical of a program that has overwritten itself,
how can you be sure that your program is even getting the correct answers?
Message has been deleted

Robin Vowels

unread,
Aug 23, 2022, 2:46:11 PM8/23/22
to
On Tuesday, August 23, 2022 at 10:30:49 AM UTC+10, Dave Tholen wrote:

> >>>>>>> The closest anyone has come is Steve Lionel, who said he could
> >>>>>>> make an argument for the second instance not being -1, but he didn't
> >>>>>>> present that argument. That ifort returns -1 upon a second READ
> >>>>>>> demonstrates that the situation is "processor dependent".
>
> >>> The situation is NOT "processor dependent". The actual numerical value
> >>> is processor dependent", but the sign of the value is NOT. The sign
> >>> is required to be positive. ifort is not standard-conforming.
>
> >> The sign is required to be positive for error conditions. From reading
> >> the entire thread, it is quite clearly debatable whether reading past
> >> the end of the file more than once is an end-of-file condition
>
> > The standard is clear and unequivocal. I quoted it in this thread.
> So has Robert Corbett:
>
> "Subclause 12.11.1 of the Fortran 2018 standard states
>
> The set of input/output error conditions is
> processor dependent."
>
> Gee, I've been saying repeatedly that the situation is processor
> dependent,
.
You are confused.
The treatment of end-of-file and of error conditions is NOT, repeat NOT processor-dependent.
It is clearly stated in all the standards since FORTRAN 77.
It is the magnitude of the numerical value returned by IOSTAT
that is processor-dependent (except for the value zero, which is returned
when there is neither an end-of-file encountered nor an error occurs).
.
The value of zero is NOT processor dependent.
.
> while you claimed (several lines above) "The situation
> is NOT 'processor dependent'". Looks like the 2018 standard agrees
> with me.
.
The 2018 standard does not agree with you.
.
> Are you seriously trying to suggest that the Fortran standards have
> all been written so well that no interpretations have ever been issued
> by the standards committee?
.
You are being ridiculous. I said that no clarifications for IOSTAT have been issued.
In fact, if you read 12.11.5 of the 2018 Fortran standard,
you will find an example that will help you understand how to make use of IOSTAT.
.
> > The standard of 1977 introduced IOSTAT and specified what happens.
> > That hasn't changed since.
> > In 44 years there has not been "clarification" because none was needed.
.
> You need to read the contributions of others in this thread. All sorts
> of "clarifications" have been made.
.
You are being silly. These are not clarifications by the standards committee.

Dave Tholen

unread,
Aug 29, 2022, 7:09:59 AM8/29/22
to
>>> Are you really trying to find the bug?

>> When I have the time to do so. The problem hasn't occurred in any recent
>> use of the program, so it hasn't been a priority.

> Your particular complaint was that the program failed when a
> print statement is inserted in it.

Incorrect. And now I understand what your problem is. Some sort of
dyslexic reading. In fact, my particular complaint was just the opposite:
adding a WRITE statement made the problem disappear.

> The error is still there.

But if the feature isn't used, the error doesn't manifest itself.

> As such an error is typical of a program that has overwritten itself,
> how can you be sure that your program is even getting the correct answers?

The same way that someone programming an image manipulation program would
know: if the sky started out blue and remained that way after manipulation.

Dave Tholen

unread,
Aug 29, 2022, 7:15:09 AM8/29/22
to
> Had you read these standards, you would have found that they all specify the same thing
> for the treatment of end-of-file and for errors, and the values that

Having trouble completing a thought?

>>>>> All say the same thing about IOSTAT since the keyword
>>>>> was introduced in FORTRAN 77 -- in regard to the
>>>>> value returned for no errors (zero), end of file (a negative
>>>>> value) and an error (a positive value).

>>>> You seem to be having trouble identifying what the issue is here. No
>>>> one is questioning whether positive is for errors and negative is for
>>>> end-of-file conditions. The issue is whether multiple reads past the
>>>> end of file are all end-of-file conditions or only the first is an
>>>> end-of-file condition.

>>> Listen up. It is an error to try to read the file after you have already received
>>> an end-of-file.

>> Listen up. I wrote in the original post that the IOSTAT value is 5001 after
>> an end-of-file has been encountered, hence I've known from the beginning of
>> this thread that gfortran treated it as an error condition. Why do you keep
>> repeating what has been noted from the beginning of this thread?

>>> You get an ERROR indication via IOSTAT..
>>> If you keep ignoring the error condition, your program can get into a loop.

>> Irrelevant, given that my program doesn't keep ignoring the error condition.

>>>>>> In reality, there
>>>>>> have been multiple Fortran standards. I have a hardcopy of one of the
>>>>>> earlier standards and have read it.

>>> Which one is that?

>> The relevant one.

> You are being evasive.

Ironic, coming from the person who evaded the reference to Subclause 12.11.1.

Dave Tholen

unread,
Aug 29, 2022, 7:43:21 AM8/29/22
to
>>>>>>>>> The closest anyone has come is Steve Lionel, who said he could
>>>>>>>>> make an argument for the second instance not being -1, but he didn't
>>>>>>>>> present that argument. That ifort returns -1 upon a second READ
>>>>>>>>> demonstrates that the situation is "processor dependent".

>>>>> The situation is NOT "processor dependent". The actual numerical value
>>>>> is processor dependent", but the sign of the value is NOT. The sign
>>>>> is required to be positive. ifort is not standard-conforming.

>>>> The sign is required to be positive for error conditions. From reading
>>>> the entire thread, it is quite clearly debatable whether reading past
>>>> the end of the file more than once is an end-of-file condition

>>> The standard is clear and unequivocal. I quoted it in this thread.

>> So has Robert Corbett:
>>
>> "Subclause 12.11.1 of the Fortran 2018 standard states
>>
>> The set of input/output error conditions is
>> processor dependent."
>>
>> Gee, I've been saying repeatedly that the situation is processor
>> dependent,

> You are confused.

Incorrect.

> The treatment of end-of-file and of error conditions is NOT, repeat NOT processor-dependent.

"Subclause 12.11.1 of the Fortran 2018 standard states

The set of input/output error conditions is
processor dependent."

> It is clearly stated in all the standards since FORTRAN 77.
> It is the magnitude of the numerical value returned by IOSTAT
> that is processor-dependent (except for the value zero, which is returned
> when there is neither an end-of-file encountered nor an error occurs).

"Subclause 12.11.1 of the Fortran 2018 standard states

The set of input/output error conditions is
processor dependent."

Says absolutely nothing about the values returned by IOSTAT.
Rather, it talks about the set of error conditions. Conditions,
not values. Got it?

> The value of zero is NOT processor dependent.

Irrelevant, given that I never claimed that the value of zero is
processor dependent.

>> while you claimed (several lines above) "The situation
>> is NOT 'processor dependent'". Looks like the 2018 standard agrees
>> with me.

> The 2018 standard does not agree with you.

"Subclause 12.11.1 of the Fortran 2018 standard states

The set of input/output error conditions is
processor dependent."

>> Are you seriously trying to suggest that the Fortran standards have
>> all been written so well that no interpretations have ever been issued
>> by the standards committee?

> You are being ridiculous.

I see that you failed to answer the question.

> I said that no clarifications for IOSTAT have been issued.

Perhaps. Has the committee even met since this issue was raised? Note that
Steve Lionel discussed the issue with Malcolm Cohen of NAG. Sounds like
one person got an informal interpretation from another person.

> In fact, if you read 12.11.5 of the 2018 Fortran standard,
> you will find an example that will help you understand how to make use of IOSTAT.

I already understand how to make use of IOSTAT.

>>> The standard of 1977 introduced IOSTAT and specified what happens.
>>> That hasn't changed since.
>>> In 44 years there has not been "clarification" because none was needed.

>> You need to read the contributions of others in this thread. All sorts
>> of "clarifications" have been made.

> You are being silly.

That Steve Lionel talked to Malcolm Cohen is a fact, not silliness.

> These are not clarifications by the standards committee.

Irrelevant, given that I never claimed that they are.

Dave Tholen

unread,
Aug 29, 2022, 8:18:54 AM8/29/22
to
> <snip>

>>> Are you really trying to find the bug?

>> When I have the time to do so.  The problem hasn't occurred in any recent
>> use of the program, so it hasn't been a priority.

> I can see some risk in that approach.

It's not a matter of risk assessment. This program is strictly used in a
hobby setting. There can be lengthy stretches of time when I simply don't
have the time to pursue the hobby. When I do have the time, that time is
usually split between adding capabilities to the program and using the
existing capabilities of the program. Out of the dozens of functions
provided by the program, there is one that is known to cause the program
to crash under certain conditions. Repeatably. Unless a WRITE statement
is added in one particular spot. Then it's fine. Annoying, but finding out
why isn't at the top of the priority list at the moment.

By way of analogy, there was a time when Microsoft's "GSA Certified to be
Correct and Complete" Fortran compiler failed to run a DO loop properly
if the step size was a variable:

ISTEP = 15
DO I=0,90,ISTEP

I reported the bug, and Microsoft acknowledged the bug. In the next
release of the compiler, was it fixed? No. They were too busy adding
new features to satisfy the many rather than fixing bugs to satisfy the
one. You and I might not agree with that approach. Depends on the type
of risk you're willing to take. One approach risked having a buggy
compiler whose reputation might suffer enough to adversely affect sales,
while the other approach risked adding new features that would appeal to
a larger potential customer base and make more money. It's a gamble.

In my case, it's not like a spacecraft will crash into the surface of Mars
if I don't find the bug.

> While you're not seeing the bug's most obvious manifestation, you don't know if it's dropping
> a random value in a random place in memory. That can be harmless ... until it's not.

Hypothetical example: if I were writing an image manipulation program, and
one feature was to crop the size of the image, and the cropping caused the
program to crash, unless a WRITE statement was added to a particular spot
in a subroutine, simple inspection of the cropped photo might reveal that
the bug is harmless. Now, if the blue sky turned green in the cropped
photo, then the bug isn't harmless. But the original photo is still there,
unaffected.

> It sounded, at least when you first posted, like you had a mysterious bug that you could reproduce. There are maintenance
> programmers out there who would be thrilled to work on a bug like that. It offers a challenge and an unknown payback: Going into it,
> you don't know what's not going to go wrong once the bug is fixed.

Yes, the crash was absolutely reproducible. Yes, the addition of a WRITE
statement made the problem go away, which was fairly mysterious.

> When I was working, I lived for bugs like this. I'd come in to the office late and I'd sit there with a cup of tea and a chocolate
> bar and Bruckner's 7th Symphony on my boombox and I'd crank up the volume and there was nobody around to complain and I'd lose track
> of time and once in a while I'd walk around and see if the sun was up (management didn't usually give window offices to people who
> liked to work at night) and by the time the normal people rolled in around 8:00 AM I'd at least have a handle on what was going
> wrong and I could share the details with colleagues who were interested and a few who weren't and then I'd go home and try to get
> some rest, secure in the knowledge that I'd done my bit and that if nobody saw me again until the next day they wouldn't miss me
> because have you ever actually listened to Bruckner?

I have nine Bruckner CDs in my collection (Symphonies 4 through 9). I
have at least one musician friend who insists that once you're heard a
Bruckner symphony, you've heard them all. Lately, however, I've been
listening primarily to other composers. In particular, the "Shout"
movement from Omar Thomas' "Come Sunday" has captured my fancy, but it's
the Baylor rendition that brings it to life. The energy, the sheer joy
of music-making, on full display.

Robin Vowels

unread,
Aug 29, 2022, 2:36:06 PM8/29/22
to
On Monday, August 29, 2022 at 9:09:59 PM UTC+10, Dave Tholen wrote:
> >>> Are you really trying to find the bug?
> >> When I have the time to do so. The problem hasn't occurred in any recent
> >> use of the program, so it hasn't been a priority.
> > Your particular complaint was that the program failed when a
> > print statement is inserted in it.
> Incorrect.
.
You don't say.
Whether the error manifests itself when you insert an innocuous statement
such as a WRITE statement, or remove it, is irrelevant.
The fact is the program exhibits symptoms of corrupting itself (that is,
of overwriting itself).
.
And you were trying to debug the program by inserting a WRITE statement.
So you knew that there was a bug somewhere.
.
> And now I understand what your problem is. Some sort of
> dyslexic reading. In fact, my particular complaint was just the opposite:
> adding a WRITE statement made the problem disappear.
> > The error is still there.
.
> But if the feature isn't used, the error doesn't manifest itself.
.
So what? The error is still evident.
.
> > As such an error is typical of a program that has overwritten itself,
> > how can you be sure that your program is even getting the correct answers?
.
> The same way that someone programming an image manipulation program would
> know: if the sky started out blue and remained that way after manipulation.
.
All irrelevant.
You have no idea what to expect when the program runs when there is a bug
somewhere.

Dave Tholen

unread,
Aug 29, 2022, 10:00:45 PM8/29/22
to
>>>>> Are you really trying to find the bug?

>>>> When I have the time to do so. The problem hasn't occurred in any recent
>>>> use of the program, so it hasn't been a priority.

>>> Your particular complaint was that the program failed when a
>>> print statement is inserted in it.

>> Incorrect.

> You don't say.

I did say. You didn't comprehend.

> Whether the error manifests itself when you insert an innocuous statement
> such as a WRITE statement, or remove it, is irrelevant.

On the contrary, it's quite relevant to your lack of understanding of the
situation at hand.

> The fact is the program exhibits symptoms of corrupting itself (that is,
> of overwriting itself).

Do you consider yourself to be a program?

> And you were trying to debug the program by inserting a WRITE statement.
> So you knew that there was a bug somewhere.

Hence the second portion of the subject line being the word "debugging".
Did you just pick up on that now, over a month later?

>> And now I understand what your problem is. Some sort of
>> dyslexic reading. In fact, my particular complaint was just the opposite:
>> adding a WRITE statement made the problem disappear.

>>> The error is still there.

>> But if the feature isn't used, the error doesn't manifest itself.

> So what? The error is still evident.

On the contrary, if the feature isn't used, the error is not evident.

>>> As such an error is typical of a program that has overwritten itself,
>>> how can you be sure that your program is even getting the correct answers?

>> The same way that someone programming an image manipulation program would
>> know: if the sky started out blue and remained that way after manipulation.

> All irrelevant.

Incorrect; given that you don't know the details of the program but I do,
you're not in a position to claim irrelevance.

> You have no idea what to expect when the program runs when there is a bug
> somewhere.

On the contrary, if I use a feature that crops an image to x by y pixels,
I expect the resulting image to be x by y pixels. Maybe there's a bug
in a routine that changes contrast, but one can look at the output image,
and if it's x by y pixels, then the cropping worked, regardless of whether
It is loading more messages.
0 new messages