$ ls /dev/null /dev/full
ls: /dev/full: No such file or directory
/dev/null
I guess in theory, you can imitate `/dev/full` by other means.Bugs in Hello World
11–20 of 262 posts
Re: Bugs in Hello World
#12Even Golang de facto suffers from this. I don't think I can name a time I saw someone check the return value of fmt.Print or log.Print. Not checking the return value still seems the the "right" thing to do.
Most Go in the wild is doing way more than a typical *nix binary, so the use case differs.
If you want a resilient system, you don't die on print and log failures.
Re: Bugs in Hello World
#13If my program writes to the standard output, but you choose to redirect the pipe to a different location, is it my program’s responsibility to check what happens to the bytes AFTER the pipe?
After all: my program did output everything as expected. The part which fucked up was not part of my program.
I can see why some projects decide to not handle this bug.
Re: Bugs in Hello World
#14Re: Bugs in Hello World
#15Re: Bugs in Hello World
#16Well that's precisely the mindset of C/C++. You have to think by yourself about everything that can go wrong with your code. And, man, lots of things can go wrong. I find more modern languages so much less exhausting to use to write correct code.
Considering that awk and TCL do not have the bug in question, while java, ruby, and node.js do, I'm not sure this can be framed in terms of modernity
Re: Bugs in Hello World
#17It does show that we take such examples a bit too literally: our feeble minds don't consider what's missing, until it's too late. That's a didactic problem. It only matters to certain kinds of software, and when we teach many people to program, most of them won't go beyond a few small programs. But perhaps the "second programming course" should focus a bit less on OOP and introduce error handling.
Re: Bugs in Hello World
#18Well that's precisely the mindset of C/C++. You have to think by yourself about everything that can go wrong with your code. And, man, lots of things can go wrong. I find more modern languages so much less exhausting to use to write correct code.
And the mindset can be to treat such conditions as "Don't Care" to allow the C/C++ code to generate more optimized assembly.
Re: Bugs in Hello World
#19Imo this is because the responsibility is not clearly defined and can be argued upon. If my program writes to the standard output, but you choose to redirect the pipe to a different location, is it my program’s responsibility to check what happens to the bytes AFTER the pipe? After all: my program did output everything as expected . The part which fucked up was not part of my program. I can see why some projects deci…
No, but it's not "after". Rather, it's your responsibility to handle backpressure by ensuring the bytes were written to the pipe successfully in the first place.
This isn't just about the filesystem being full btw. If you imagine a command like ./foo.py | head -n 10, it only makes sense for the 'head' command to close the pipe when it's done, and foo.py should be able to detect this and stop printing any more output. (This is especially important if you consider that foo.py might produce infinite lines of output, like the 'yes' program.)
I would argue this is not necessarily even an error from a user standpoint, so the return code from food.py should still be zero in many cases—a pipe-is-closed error just means the consumer simply didn't want the rest of the output, which is fine [1], whereas an out-of-disk-space error is probably really an error. Handling these robustly is actually difficult though, because (a) you'd need to figure out why printf() failed (so that you can treat different failures differently—but it's painful), and (b) you need to make sure any side effects in the program flow up to the printf() are semantically correct "prefixes" of the overall side effect, meaning that you'd need to pay careful attention to where you printf(). (Practically speaking, this makes it difficult to even have side effects that respect this, but that's an inherent problem/limitation of the pipeline model...)
FWIW, I would be very curious if anyone has formalized all of these nuances of the pipeline model and come up with a robust & systematic way to handle them. It seems like a complicated problem to me. To give just one example of a problem that I'm thinking of: should stderr and stdout behave the same way with respect to "pipe is closed"? e.g. should the program terminate if either is closed, or if both are closed? The answer is probably "it depends", but on what exactly? What if they're redirected externally? What if they're redirected internally? Is there a pattern you can follow to get it right most of the time? There's a lot of room for analysis of the issues that can come up, especially when you throw buffering/threading/etc. into the mix...
[1] Or maybe it isn't. Maybe the output (say, some archive format like ZIP) has a footer that needs to be read first, and it would be corrupt otherwise. Or maybe that's fine anyway, because the consumer should already understand you're outputting a ZIP, and it's on them if they want partial output. As always, "it depends". But I think a premature stdout closure is usually best treated as not-an-error.
Re: Bugs in Hello World
#20Well that's precisely the mindset of C/C++. You have to think by yourself about everything that can go wrong with your code. And, man, lots of things can go wrong. I find more modern languages so much less exhausting to use to write correct code.
Modern languages do catch more programmer errors than C/C++, but the more general point is that there are "edge cases" (redirecting to a file isn't an edge case) that developers need to consider that aren't magically caught, and understanding the language you use well enough so as not to write those bugs is important.
The more experience I get as a dev the more I've come to understand that building the functionality required in a feature is actually a very small part of the job. The "happy path" where things go right is often trivial to code. The complexity and effort lies in making sure things don't break when the code is used in a way I didn't anticipate. Essentially experience means anticipating more ways things can go wrong. This article is a good example of that.