Eric said:
[...]
Anyhow, if we ignore that problem, and the other bizarre ANSI-ism that
you can't seek to some offset you haven't previously visited
[... in a text stream ...]
Lots of people (including some who ought to know better)
are seduced by the notion that one can do arithmetic on the
"file position indicators" of text streams. In Standard C,
this is not reliable and leads to undefined behavior.
Some people who have learned the above profess that
Standard C is to blame for this sad situation. Such people
have had but limited experience of different systems' notions
of "file," and would do well to refrain from insulting those
whose knowledge is greater. It is better to remain silent and
risk suspicion of folly than to open one's mouth and confirm it.
ANSI C contains two functions which satisfy this: fgetpos(), and
fsetpos(). Notice how they used a data type (fpos_t) that does not
imply any arithmetic capabilities?
So you're saying people who see fseek/ftell which clearly uses "long
int" as the file position are not natually supposed to assume they can
do file pointer arithmetic, especially in light of the knowledge that
functions with more restrictive semantics exist as seperate functions?
I am well aware of systems that have a hard time with byte by byte file
offsets. One such obscure system is Windows 98. The difference is,
rather than simply punting and implementing some obscure kind of fseek,
they bit the bullet and did the obvious, but very slow, implementation
that at least behaved consistently.
Then again, there's always the faint possibility that the
Young Turks have a better idea than the Old Fogeys. If so,
let's hear about the better idea
Oh it may surprise you. The first thing I would start with is to stop
idolizing the original creators and/or the C standard, and recognize
when mistakes have been made.
You want an improvement? Not a problem:
#include <stdio.h>
#include <stdint.h>
int fseekB (FILE * fp, intmax_t offs);
The value offs is always taken as an offset (in bytes) from the
beginning of the file, if the offset does not refer to a valid file
position, -1 is returned and errno is set. No value of offs can lead
to UB so long as fp is a valid and active file.
#include <stdio.h>
#include <stdint.h>
intmax_t ftellB (FILE * fp);
The value returned is the exact offset in the file where the
corresponding to the next byte to be read/written. For a valid
non-empty file pointer fp, fseekB (fp, ftellB (fp)) is basically a
NO-OP. At EOF, the position returned is the length of the file. The
function properly observes ungetc(), and all other or ordinary file
operations.
These functions can retain the property of UB, that the ANSI C
committee cherishes so much, if fp is not a valid open file.
Personally, I would prefer that errors be returned if fp is either NULL
or a *closed* fp.
What could be simpler?
If a system has problems implementing it, then that's too bad. The x86
and 68K world implemented entire floating point emulators just to be
compliant with the C standard, a little work on the part of others
won't kill them. And as Microsoft and others have demonstrated -- its
not actually an impractical thing to implement.
If that doesn't work for you, then point me out one system where 1) it
would be impractical to implement this, and 2) which has a working C99
compiler on it. The marginal platforms are not going to be updated
beyond C89 anyways, so there is little sense in making provisions for
them.
-- but let's hear about it
without gratuitous insults. We stand on the shoulders of
giants; [...]
Its hard to *stand* if you are grovelling all the time.