5 ms·
I know C well enough to know that writing C to avoid every edge case left undefined by the standard is a fool's errand. There are a bunch of problems with this
by kerkeslager 3y ago
I know C well enough to know that writing C to avoid every edge case left undefined by the standard is a fool's errand. There are a bunch of problems with this approach:
a. Your target ecosystem(s) probably follows a few norms in cases not defined by the standard. If it works on the target ecosystem(s), nobody cares if it's non-standard. Testing on the target ecosystem, preferably automated testing, is the standard that matters.
b. Some of these norms are extraordinarily powerful. For example, check out NaN boxing[1]. Standard? Hell naw. Useful? So useful that it's practically mandatory for dynamic PL interpreters to compete on performance.
c. So let's say you're targeting an ecosystem that does some atypical stuff, i.e. doesn't follow the norms mentioned. Well, joke's on you, off-the-beaten-path ecosystems typically also have bleeding-edge tooling that doesn't implement the standards. So again, testing on the target ecosystem, preferably automated testing, is the standard that matters.
d. So let's say you're targeting a lot of ecosystems, so many ecosystems that you can't reasonably test on all of them, like if you're writing NetBSD or the JVM. Okay, well, the edge cases of the C standard still don't matter because you just shouldn't be using any of the off-the-beaten-path parts of the C standard anyway, since those parts are the parts which aren't implemented in lots of obscure architectures.
e. And sure, if you really just enjoy being annoyingly pendantic you can go and learn the whole C standard and go write your own blog test with integrated quiz and then condescendingly tell people they don't know C, with the implication that you do know C. But the reality is that knowing those weird edge cases of C isn't useful because if you actually use those edge cases of C then nobody else on your team can read your code.
f. And lastly, there's plenty of defined behavior which you shouldn't use, too. Just because you know what it does, doesn't mean the next person reading your code knows.
My answers to the questions in the test:
1. 8 on most ecosystems. If it matters, test it, but if it matters you probably need to use one of the non-standard extensions mentioned to do anything about it, so the standard didn't matter so much did it?
2. 0 on most ecosystems. But frankly, don't use `short int`, ever. Use int with the limits defined in `limits.h` if you just want the most efficient integer width, and if you need a specific integer width use the the types in `stdint.h`. Yes, I'm aware that `int` isn't defined as the most efficient in the standard, but `int` is one of the first things people implement in a C compiler so the likelihood of coming across an int that isn't the fastest integer size is absurdly small.
3. Play stupid games win stupid prizes. Who cares if this is defined? Even if it were defined it would be bad code. Don't multiply chars, FFS.
4. Play stupid games win stupid prizes. Obviously bit twiddling when you don't know teh structure of the bits is bad. The fact that Endianness is relevant in bit shifts and yet is not brought up by the author does in fact show the dangers of smugly pretending you know C better than other people.
5. Play stupid games win stupid prizes. Who cares if this is defined? Even if it were defined it would be bad code because depending on the pre/postfixedness of ++ is hard for most people to reason about.
[1] https://craftinginterpreters.com/optimization.html#nan-boxing https://craftinginterpreters.com/optimization.html#nan-boxin...