Live data from Hacker News

EOF is not a character

ruslanspivak.com

131–136 of 136 posts

Re: EOF is not a character

#131
post #19

Like 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…

You may be interested in tagged unions. A struct with an enum and a Union. You can switch on the enum.

More stuff like this in https://pdfs.semanticscholar.org/31ac/b7abaf3a1962b27be9faa2...

Re: EOF is not a character

#132

Earlier quoted context omitted.

... which is why no system ever implements things this way. There are many portions of the C spec that can be ignored. 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.

TI DSPs with 16-bit char are still being made. It's a niche thing that most people will never need to care about, but it's not just a historical quirk and definitely not "no system ever".

Then there's SHARC with its 32-bit char.

Do architectures like that have non-freestanding C implementations, though? It's kinda moot if there's no getchar()...

Re: EOF is not a character

#133
post #124

Earlier quoted context omitted.

The EOF condition for stdio functions is supposed to be sticky, although glibc didn't implement it correctly until 2.28: https://sourceware.org/bugzilla/show_bug.cgi?id=1190 https://sourceware.org/legacy-ml/libc-alpha/2018-08/msg00003... > All stdio functions now treat end-of-file as a sticky condition. If you read from a file until EOF, and then the file is enlarged by another process, you must call clearerr or anot…

Wow, very interesting! That sounds like a somewhat significant change, and I wonder how much stuff will be broken by it. Although interestingly somehow I'm still seeing the old behavior in Debian Buster with glibc 2.28 with python3. import sys while True: b = sys.stdin.read(1) print(repr(b)) With old glibc with both python2 and python3 the EOF isn't sticky (as expected). With 2.28 with python2 the EOF is sticky (like…

In Python 3, file I/O is is implemented using POSIX read(), write() etc., rather than C stdio.

Re: EOF is not a character

#134
post #116
post #107

Earlier quoted context omitted.

Structs are values and you can return them like any value (or use them as parameters). I'm not sure what you mean about compilers.

Xe is conflating compilers and calling conventions a bit. The way that structure types are returned varies by calling convention, as indeed do a lot of other things. Mismatched calling conventions leads to problems. But structure type return values are well specified for most calling conventions, and quite a number of compilers support explicitly specifying the calling convention for mixed-language or mixed-compiler…

Many calling conventions apparently use a method for returning structs which is inherently non-thread-safe.

Also from that link:

> 32-bit cdecl calling convention

> For return values of structure or class type, there is wide incompatibility amongst compilers. Some make the return thread-safe, by breaking compatibility with the 16-bit cdecl calling convention. Some retain compatibility, at the expense of their 32-bit cdecl calling convention not being thread-safe. The ones that break compatibility don't all agree with one another on how to do so.

Re: EOF is not a character

#135
post #133

Earlier quoted context omitted.

Wow, very interesting! That sounds like a somewhat significant change, and I wonder how much stuff will be broken by it. Although interestingly somehow I'm still seeing the old behavior in Debian Buster with glibc 2.28 with python3. import sys while True: b = sys.stdin.read(1) print(repr(b)) With old glibc with both python2 and python3 the EOF isn't sticky (as expected). With 2.28 with python2 the EOF is sticky (like…

In Python 3, file I/O is is implemented using POSIX read(), write() etc., rather than C stdio.

Interesting, and EOF on POSIX read() isn't supposed to be sticky?

That seems like a weird situation, that EOF is sticky in some cases but not others.

Re: EOF is not a character

#136

Earlier quoted context omitted.

In the end, integers, floating point numbers, "text\n", emojis etc. are just sequences of bytes. You choose to acknowledge it and take advantage of it, or you don't.

By that argument, why even have types... and what makes bytes so special? Perhaps you'd like to work with bitstreams, (or qbitstreams)?

A bit late, but bytes are very often the smallest addressable unit. That's why they are "special".

Which answers your second question: "bitstreams" would be terrible because they are not well connected with a hardware reality. Unless you have bitstream-oriented CPU, it is a bad idea for a basic type to go against the hardware.

Why even have types... Well, yes, there are languages without type checking where the notion still exists. For instance Forth has no type checking but two types are implied: the "byte" type and the "machine word size" type, maybe three if you count strings.

Post reply on HN