3 ms·
"Since you're a careful programmer, you are therefore smart and you never call a null function pointer." I don't think that's remotely justifiable to assume in
by dale_glass 6y ago
"Since you're a careful programmer, you are therefore smart and you never call a null function pointer."
I don't think that's remotely justifiable to assume in modern times. There's 150K lines of C code in the curl repository, with commits from 862 authors, 555 of which ever only made a single commit.
There's no doubt that some of those will be less than perfect, or have an off day, or just not be familiar enough with the code, or that somebody will mess up a merge and remove a line too many.
- jcranmer 6y agoThis is the crux of the problem. When I put on my security hat, I absolutely agree with you: we should give safety rails to programmers, because decades of experience have shown that programmers are incapable of writing correct code without them. But when you go around and start talking to most C programmers, they don't want those safety rails, they instead want maximum performance. I won't name and shame anyone specific here, but comments along the lines of "we write in C because it keeps all the idiot programmers out of our project" are not unknown. (And then some of those people turn around and complain when the compiler didn't compile their broken code in the way they expected it to, ugh.) To me, the biggest problem with C isn't that it has undefined behavior, nor that it lacks the safety rails. It's that it gives you undefined behavior while simultaneously avoiding giving you any tools to enforce avoidance of it (and in a couple of cases, it downright encourages you to commit it. Try checking for signed integer overflow without triggering it!). Contrast this to Rust. Rust doesn't have any less undefined behavior--it actually has even more cases that are undefined--but at the same time, it makes it harder to actually go trip over those cases. In the function pointer example, your basic function pointer is required to be non-null, and it's annoying to construct a null function pointer, so you instead it wrap it in Option. But once it's in Option, there's no (easy) way to call it without first making sure that it's non-null, so you end up with code that can never actually call a null function pointer.