4 ms·
Maybe C?
by munificent 3y ago
Maybe C?
- actionfromafar 3y agoYou can definitely get there with C but the language isn’t actively pushing you into horror.
- segfaultbuserr 3y agoIt's the "unsurprising" part in "unsurprising & horrifying" - if you manipulate raw pointers incorrectly, of course it will crash or be vulnerable, to the surprise of no one by design.
- actionfromafar 3y agoThis rings true the more I think about it. Any large code base gets there with size, but with C one gets there pretty reliably after a certain heft of code.
- segfaultbuserr 3y agoThat being said, while C's surprises are certainly fewer than other languages, it still does have a few surprising corner cases in contrary to its usual "portable assembly" character (without compiler optimization) - implicit type promotion in expressions with mixed data types, potential malloc() in printf(), possibility of Duff's device, and the likes. A Sun engineer Peter van der Linden has a book Expert C Programming, Deep C Secrets that explores these topics.
- munificent 3y agoIt doesn't actively push you there, which is why it's on the bottom half. There is a fairly coherent mental model for C and once you have it, the language rarely surprises you. But when it does surprise you, it's almost never anything good. Stuff like Duff's device, `3[someArray] = value`, etc. The surprises are always the language's raw machinery showing through in unpleasant ways, and never a delightful bonus feature the designers added for you.
- trealira 3y ago> The surprises are always the language's raw machinery showing through in unpleasant ways, and never a delightful bonus feature the designers added for you. I was reading "Writing Solid Code" by Steve Maguire (though it should really be called "how to write code in C without shooting yourself in the foot"). One thing that surprised me, but which made sense, was that pointers can overflow. It's unlikely, and ANSI non-compliant, but something possible nonetheless. Hence, Maguire said that this code: void *memchr(void *pv, unsigned char ch, size_t size) { unsigned char *pch = (unsigned char *)pv; unsigned char *pchEnd = pch + size; while (pch < pchEnd) { if (*pch == ch) return (pch); pch++; } return (NULL); } Has a bug. It surprised me when reading it, because it's such a common language idiom. "What range of memory would memchr search when pv points to the last 72 bytes of memory and size is also 72? If you said 'all of memory, over and over,' you're right. Those versions of memchr go into an infinite loop because they use a risky language idiom—and Risk wins." So, he said that that code should be replaced with this code: void *memchr(void *pv, unsigned char ch, size_t size) { unsigned char *pch = (unsigned char *)pv; while (size-- > 0) { if (*pch == ch) return (pch); pch++; } return (NULL); } Just the little things C lets you think about. This seems like a bug that would occur every once in a blue moon.
- JonChesterfield 3y agoGone through a whole range of emotions looking at this. Tried to put together an argument about the high bits of (common) address spaces being zero and therefore it's safe but I don't think that works. It's the while (i++ < UINT32_MAX) bug in different clothing. Would make for a cruel take on the interview question of "tell me what bugs you see in this function".
- trealira 3y ago>Tried to put together an argument about the high bits of (common) address spaces being zero and therefore it's safe but I don't think that works. Yep; on AMD64, bits 48 through 63 must be identical to bit 47, which can be 1 or 0, akin to sign extension. In practice, I don't think any sane OS would let you reserve the very last n bytes of memory, especially not with an address space as large as that of AMD64, but you can't assume the architecture, and you don't always have an operating system. And yeah, you could see the same bug with integer array indices, if signed integers wrap. /* Endless loop if end == INT_MAX */ for (int i = 0; i < end; ++i) /* code */;
- taneq 3y agoThe Undefined Behaviour In The Walls, slowly driving you mad even if your program runs perfectly.