From: glen herrmannsfeldt on
Richard Maine <nospam(a)see.signature> wrote:
> glen herrmannsfeldt <gah(a)ugcs.caltech.edu> wrote:
>> feenberg <feenberg(a)gmail.com> wrote:

>> > What about initializing n to some impossible values and then:

>> > comment(last:last)='/'
>> > write(99,*) comment
>> > read(99,*) n(i),i=1,max

>> > The / will terminate the free format read without an error, and then
>> > you can count the number of valid n() values. The items not read from
>> > unit 99 will retain their initialized values. I wouldn't trust i to
>> > be any particular value, though.

>> Last I knew, the standard didn't require either i, nor n() to
>> have the appropriate values in the case of an incomplete read.
>> (I would put either END= or ERR= on, or it likely fail in other ways.)

> The standard doesn't talk about "incomplete reads" in such general
> terms. What you say would be true for end of file or error conditions,
> but it is not the case for a '/' terminator

I had forgotten how the '/' works, but then someone could
always forget to put one on...

> A '/' terminator does leave appropriate values in n (I'd have to go read
> more carefully to figure out the status of i). In particular, it "causes
> termination of execution of that input statement after assignment of the
> previous value." Note the "after assignment of the previous value" part.
> Also, "If there are additional items in the input list, the effect is as
> if null values had been supplied for them." Note that supplying null
> values is not at all like hitting an end of file. It is more comparable
> to the blank padding that applies to some explicit format reads.

I, and some other, like to have programs read to the end of a file
and appropriately process the data read. In the case of internal
read, I suppose one can be sure to append the '/'.

> I'm puzzled, by the way, as to why you would expect an end= to be useful
> in this context, which involves a list-directed read with a '/'. The '/'
> should stop the read before an end-of-file becomes relevant. I suppose
> the '/' could possibly get "swallowed" by a prior unterminated character
> string, but that's a bit arcane, particularly for numeric data; you'd
> probably get an error for having the wrong data type first. It is true
> that the code as shown (after adding the needed parens) would get an
> end-of-file, but that is more appropriately addressed by fixing the
> coding error (lack of a rewind) than by leaving the error in and adding
> a handler for it.

> I would also generally disagree with unqualified advice to add end= and
> err=. I'm not quibbling about the distinction between those and iostat=
> (which I usually prefer), but rather about the unqualified nature of the
> suggestion. I would say that adding end= or err= (or iostat=) should be
> done *ONLY* if you intend to do something useful after detecting those
> conditions.

Yes, I completely agree that they should only be used when
there is something useful to do. Most C I/O functions return
a status value in the case of errors, which is way too easy
to ignore. One of the easiest to ignore is on fclose(), since
it would seem that one should be done by then, and that nothing
(else) could go wrong. Often the last (or only) buffer is written
on close, which could fail for many reasons.

So, yes, I like to have programs detect and report end-of-file
when it occurs in the wrong place, and process as appropriate
when in the right place. Also, even when it is in the wrong
place, there is often something that can be done. Otherwise,
the error message generated often includes the line number in
the input file, where that isn't available with END=.
It depends on the program and expected file input.

> The reason I am being picky about what might seem such an
> obvious point is that I have seen people mislead by such unqualified
> recommendations. They heard somewhere that they are supposed to put such
> things on all I/O statements, so they do that. But lacking any plan of
> subsequent action, they then ignore the detected conditions. That is
> usually far worse than leaving the specifiers off and letting the system
> take its default action, which will usually be an error message.

It depends on the program, but yes. Sometimes there are important
things to do, write out final data, etc., before terminating.
Detecting and ignoring EOF is likely worse than the system
generated message.

> If you think you can generate a more useful error message than the
> system is likely to, that's fine. It is sometimes the case in that you
> might be able to provide better context. Or if you have alternatives
> other than just an error message, that's even better. (In some
> interactive cases, you can ask for a correction.) But don't just put in
> an err= because someone suggested that you should do that, thinking that
> just putting it in adequately followed the advice.

Well, that is generally useful advice in programming, and even
in life. That is, doing things because someone suggested it,
but not knowing the reason for the suggestion, often gives
surprising results.

> I do have a different criticism of feenberg's suggestion, though. I
> think that the general notion of appending a '/' is a good one. But it
> seems like an unnecessary complication to use a temporary file. That
> adds all kinds of potential failure modes. Forgetting the rewind, as the
> code shown does, is only one of many messier ones. Having added the '/'
> to the "comment" variable, I'd just do an internal read from it.

At which point it would be useful to know if i was the desired value.

> Admitedly, list-directed reads from internal files have only been
> standardized for 20 years now. But some compilers older than that
> allowed it as an extension. :-)

>> The restrictions on this likely go back to the 704 index registers,

> I doubt it. I suspect it as having more to do with things like
> buffering. I recall such things being discussed in committee. While I
> don't recall all the details, I'm quite sure that the subject of 704
> index registers never was mentioned.

Implied-DO does go back to Fortran I. Sometimes it seems that
some things took way too long to change.

-- glen

From: glen herrmannsfeldt on
Richard Maine <nospam(a)see.signature> wrote:
(snip)

>> OK, but q would not normally be valid in an integer.

> I thought we were just advocating consistency? :-) I hope consistency
> doesn't mean having different rules for how errors are handled for
> integers and reals. I realize that the allowed forms are different, but
> I would not expect different error handling. I cited that case because
> it is one where I personally have observed different behavior on
> different compilers. It seemed to me that the one case was sufficient fo
> rthe point. (I have observed others also, but the one seemed enough to
> mention.)

Well, you could allow any letter for an exponent, which should
be general enough. But otherwise, conversion errors don't
seem quite the same as some other errors. If you have a parity
error on a disk read, there really isn't much you can do with the
characters you get. The character read is likely not the one
the user entered. The system might even be unstable if errors
then start to appear in the swap file.

Otherwise, it seems that if there is a question about the right
way to do it, the usual solution is an option on the OPEN
statement.

>> Well, I was discussing the detection of end-of-file, and the
>> ability to read and count the list items up to that point.

> End-of-file is a very different matter from error conditions - very
> different. In all of the above, I was talking about error conditions. I
> replied to your example of reading 1e2 into an integer, which nothing to
> do with end-of-file. If you switch back and forth as to whether you are
> talking about end of file or error conditions, don't be surprised if I
> have trouble following the switch and thus give strange replies.

Well, note also that reading 1e2 in %d format is not an error in C.
The %d stops before the e, which may be read in another format
or in a future read.

> End-of-file is at least a well-defined in terms of the Fortran standard.
> My arguments about the problems with error conditions mostly don't
> apply. So on end of file...

> But end-of-file is also a pretty special case. I wonder how often it
> would be useful to count list items for that particular case. By
> definition, it only comes up on the last read. If you have insufficient
> data for any read other than the last, you'll just be reading the wrong
> data instead of an end-of-file. That seems to suggest that depending on
> it is a shaky practice in that it breaks if you ever want to add any
> subsequent input, imbed the code in something else, or loop it to do
> multiple cases.

Sometimes you know that, other times you don't.

> Would we want to go out of our way to encourage that?

It seems to me that just having a feature doesn't need to
encourage its use. If a feature has some good uses, and others
that should be discouraged, removing it from the language or
not adding it seems unnecessary.

> Also, for most reads that hit an end of file, the count is going to be
> zero. The only way for it to be non-zero would be to have a multi-record
> read, as can happen with namelist, list-directed, formats with a "/" and
> format reversion.

I was noticing not so long ago that even in Fortran 2003 the
restrictions on END statements are still there. For fixed form:

"The program unit END statement shall not be continued.
A statement whose initial line appears to be a program
unit END statement shall not be continued."

Now, I agree that there isn't much reason to continue an
END statement, or to have a statement starting with END be
continued, but it still seems like a strange restriction.
It isn't that hard to do if anyone wanted to do it.

> I don't see any huge reason why one couldn't have some kind of count
> indication on hiting end of file. That might mean I just don't see it.
> But I do wonder about how useful it would be for the above reasons.

So if I find enough less useful features already in the language
that would be a good reason to add it?

-- glen
From: Ron Shepard on
In article <hu705k$eig$1(a)speranza.aioe.org>,
glen herrmannsfeldt <gah(a)ugcs.caltech.edu> wrote:

> As far as I know, no C compiler accepts either D or Q (or d or q)
> as an exponent indicator, but it is possible. (The standard allows
> for e or E only.)

There are other valid floating point forms that are not recognized by
other languages. I don't know about C in particular, but many of the
lesser languages do not accept things like "123+123" as equivalent to
123.0e123 or 123-123 as equivalent to 123.0e-123.

$.02 -Ron Shepard
From: Richard Maine on
glen herrmannsfeldt <gah(a)ugcs.caltech.edu> wrote:

> So if I find enough less useful features already in the language
> that would be a good reason to add it?

I assume that was meant humorously, but then sometimes it is hard to
tell. Just in case....

No. Adding *ANYTHING* to the language requires quite a lot of
justification. There is always a long list of features that people want.
Arguments along the line of "seems like a nice idea; why not?" don't
even come close to flying.

Adding a feature takes work. That is so for even the most
trivial-seeming of features. Something like this one probably isn't
particularly hard, but it is a lot more work than I bet you are
envisioning. One has to look at all the interactions with other
features. Some of those interactiosn will *NOT* be obvious at first; I
guarantee it; they pretty much never are. Anyone who proposes a feature
and claims that it will be practically no work is imediately at a
disadvantage of not sounding plausible, insomuch as many features have
been proposed with such claims, but then turned out to be far, far more
work than initialy alleged.

To get any feature in, you have to argue that it has better cost/benefit
(dunno why it is always described as cost/benefit, when benefit/cost
seems like a more appropriate way to put it) than other features
competing for the same work. There are always other features competing
for the same work.

Oh, and even volunteering to do all the work doesn't hack it because you
can't. Even if you write every word of the changes, the rest of the
committee (and outside reviewers) have to review it.... and more often
than not, find that it has major problems that need further work. I've
been there before - having someone submit an allegedly complete job
which has to be thrown out and redone.

--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
From: Clive Page on
In message <hu65hh$60j$1(a)speranza.aioe.org>, glen herrmannsfeldt
<gah(a)ugcs.caltech.edu> writes
>C does it character by character (as in stream I/O), and stops
>when conversion fails, leaving the unusable character in
>the stream. (Note: see the ungetc() function.)
>
>With scanf(), if you read the above line with %i format it will
>read the 1, leave the e2 on the input stream, and return 1 as
>the number of values successfuly read.

You can use stream I/O in Fortran nowadays - it's in the F2003 Standard
and already supported by gfortran, g95, and other fine vehicles.
Unfortunately Fortran doesn't supply a scanf() function, but I shouldn't
think it would be too hard to write one.

I wrote a short and rather basic tutorial some time ago; when I get time
maybe I'll expand it a bit...
http://www.star.le.ac.uk/~cgp/streamIO.html

--
Clive Page