CP/M and DOS use ^Z (0x1A) as an EOF indicator. More modern operating systems use the file length (if available). Unix/Linux will treat ^D (0x04) as EOF within a stream, but only if the source is "cooked" and not "raw". (^D is ASCII "End Of Transmission or EOT" so that seems appropriate, except in the world of unicode.)
That is a common misconception. http://jdebp.info/FGA/dos-character-26-is-not-special.html
EOF is not a character
81–90 of 136 posts
Re: EOF is not a character
#82Earlier quoted context omitted.
I strongly disagree. The existing getchar() API is not simple at all! All the possible error conditions are still there, they're just obscured by an overstreamlined API which fuses them inappropriately into a single return type. That makes it harder to handle all cases well, because you have to do all the work manually.
The man page for getchar is a single, easy to read paragraph. To understand algebraic types you need a couple of textbooks.
Re: EOF is not a character
#83Earlier quoted context omitted.
The man page for getchar is a single, easy to read paragraph. To understand algebraic types you need a couple of textbooks.
No, encoding additional information in unused bits of an int that you return is stupid over-engineering that needs multiple textbooks to grok. Option , on the other hand, is the simplest possible solution for this problem.
What kind of wicked education you had for this to be the case?
My dad taught me about bits and bytes and words when I was a kid, and by 16 I had a quite solid grasp of it (without any textbook). Then I studied several years and got a phd in applied math (mostly numerical pde, and that involved a lot of programming). Then I have spent 15 more years doing math and programming in several languages (mostly C and Python) and getting paid for teaching data science and signal processing to people who got on to have fruitful jobs in industry. Today, I read the wikipedia page about "option type" [1] and the one about about type theory [2], which seems a prerequisite, and couldn't understand a word.
Re: EOF is not a character
#84Like NULL, confusion over EOF is a problem which can be eliminated via algebraic types. What if instead of a char, getchar() returned an Option ? Then you can pattern match, something like this Rust/C mashup: match getchar() { Some(c) => putchar(c), None => break, } Magical sentinels crammed into return values — like EOF returned by getchar() or -1 returned by ftell() or NULL returned by malloc() — are one of C's dra…
#include
struct { int err; char c; } myfunc() {
return { 0, 'a' };
}
int main(int argc, const char *argv[]) {
{ int err; char c; } = myfunc();
if (err) {
// handle
return err;
}
printf("Hello %c\n", c);
return 0;
}
This is (semantically) perfectly possible today, you just have to jump through some syntactic hoops explicitly naming that return struct type (because among others anonymous structs, even when structurally equivalent, aren't equivalent types unless they're named...). Compilers could easily do that for us! It would be such a simple extension to the standard with, imo, huge benefits.Every time I have to check for in-band errors in C, or pass a pointer to a function as a "return value", I think of this and cringe.
Re: EOF is not a character
#85Earlier quoted context omitted.
> If by procedural you mean, nonsense, then sure Why are you being snarky? They clearly mean the issue of modelling partial functions which would normally be done by a side-effect in a procedural language but can’t in a functional language.
No, they imply that the handling is done by returning a negative number. I'm being snarky, as is my nature, to highlight the madness of a function called `getchar` returning anything but a `char`.
It’s effectively returning a Maybe(char).
Re: EOF is not a character
#86Earlier quoted context omitted.
No, encoding additional information in unused bits of an int that you return is stupid over-engineering that needs multiple textbooks to grok. Option , on the other hand, is the simplest possible solution for this problem.
> No, encoding additional information in unused bits of an int that you return is stupid over-engineering that needs multiple textbooks to grok. Option , on the other hand, is the simplest possible solution for this problem. What kind of wicked education you had for this to be the case? My dad taught me about bits and bytes and words when I was a kid, and by 16 I had a quite solid grasp of it (without any textbook).…
You do not need to understand theoretical type theory to understand options. It's just like a pointer that can be NULL except the compiler makes sure you can't accidentally dereference it if it is. Algebraic data types in general are basically just structs and tagged unions, except the compiler makes sure you can't screw the tags up.
Like, dude, by your own account, you're pretty smart; that's the point of your last paragraph, right? There are, at this point, hoards of Rust and Scala and Swift and Kotlin programmers who can figure out how option types work, and don't seem to have too much of a problem with it and pretty much universally think they're great. Are they actually just smarter than you?
Re: EOF is not a character
#87Seems like the confusion arises because getchar() (or its equivalent in langauges other than c) can produce an out-of-band result, EOF, which is not a character. Procedural programmers don't generally have a problem with this -- getchar() returns an int, after all, so of course it can return non-characters, and did you know that IEEE-754 floating point can represent a "negative zero" that you can use for an error cod…
The amusing thing about it is that C does not guarantee that EOF is out-of-band! ISO C says that char must be at least 8 bits, and that int must be at least 16. It is entirely legal to have an implementation that has 16-bit signed char and sizeof(int)==1. In which case -1 is a valid char, and there's no way to distinguish between reading it and getting EOF from getchar().
Large swaths of the C standard were built during the heyday of computer design, when you had all sorts of wacky sizes, behaviors and abstractions. Lots of "undefined behavior" is effectively deterministic, because all modern computers have converged to do so many things the same way.
Re: EOF is not a character
#88Like NULL, confusion over EOF is a problem which can be eliminated via algebraic types. What if instead of a char, getchar() returned an Option ? Then you can pattern match, something like this Rust/C mashup: match getchar() { Some(c) => putchar(c), None => break, } Magical sentinels crammed into return values — like EOF returned by getchar() or -1 returned by ftell() or NULL returned by malloc() — are one of C's dra…
What always annoyed me about C is that it has all the tools to simulate something approaching this, save for some purely syntactical last-mile shortcomings. We can already return structs; if only there were a way to neatly define a function returning an anonymous struct, and immediately destructure on the receiving end. Something like: #include struct { int err; char c; } myfunc() { return { 0, 'a' }; } int main(int…
#include
#include
std::tuple myfunc() {
return { 0, 'a' };
}
int main(int argc, const char *argv[]) {
auto [ err, c ] = myfunc();
if (err) {
// handle
return err;
}
printf("Hello %c\n", c);
return 0;
}Re: EOF is not a character
#89CP/M and DOS use ^Z (0x1A) as an EOF indicator. More modern operating systems use the file length (if available). Unix/Linux will treat ^D (0x04) as EOF within a stream, but only if the source is "cooked" and not "raw". (^D is ASCII "End Of Transmission or EOT" so that seems appropriate, except in the world of unicode.)
That is a common misconception. http://jdebp.info/FGA/dos-character-26-is-not-special.html
For binary files, you just assume there is padding at the end of the file to the end of the sector. For text files, the SUB code was used to indicate where the file ended.