I wrote, too optimistically:
It's easy to write correct string operations, even in C, even for null-terminated strings in fixed-size buffers — and security-conscious C programmers often do.
Barry Kelly objected:
I don't agree that it is easy [...] to write correct code in C for manipulating null-terminated strings in fixed sized buffers, for a simple reason: if you can't let the fixed length follow the string, either via static typing or dynamically, then normal procedural abstraction will tend to hide the length and lead to errors later.
I didn't find that very convincing until a few weeks ago, when I spent a late night tracking down a mysterious buffer overflow: I had used a “safe” string operation with the wrong buffer size.
I find it so hard to believe the amount of bugs and pain we endure for the sake of a few cycles.
ReplyDeleteOptimization has an immediate payoff in feelings of superiority and real-programmer-hood; safety generally has no emotional reward. That may explain a lot.
ReplyDeleteBut at least in this case, it's less for the sake of cycles than from programmer conservatism. std::string is better for most things, but convincing people to use it is hard, especially when it doesn't come with sprintf or amortized-linear-time appending. (I ran into that last one recently.)
Consider the following: gopher://zzo38computer.cjb.net:70/0quiz.menu*d
ReplyDeleteThis program does not use string buffers for anything other than configuration data (which is known to be safe); most things are just copied and parsed directly. This shows that in some cases you do not need to make buffers for some things if you just read one character.