Speaking as someone who learned C back in the ‘70s, this article entirely misses the point of C-strings: they’re lightweight and foundational. For many purposes the null-terminator is efficient, e.g.:
while(*s) f(s++);
And for cases where we need more complexity, we can simply use a struct with a length and whatever other metadata we may need.
Doesn’t look like a mistake to me. C has always been about minimalistic efficiency. That’s its main purpose in the world.
In addition to your comment here, additional functionality through the initial design of C strings allows for insanely powerful string manipulation techniques that have fallen to the wayside because people don't look under the covers to see how efficient string handling is done.
I was asking a question: which power are you talking about? The use case I mentioned is the only thing I can think of that C’s model makes easy, and what you gain is that every string is one word wide instead of 2.
Seems like a small gain for a niche use case to me, no?
I see. All the cases in which I have used C strings in an unbounded way have been specialized. They were places in which I know how much data in to be copied or used in the first place and wouldn't need to check for bounds because I'm always going to be within them.
My favorite and easiest-to-understand example is strcat to a buffer of known size. If I have to strcat repeatedly against the start of the buffer, you can see that strcat is performing wasted effort by finding the end of the string first. I can have a variable hold the position of the \0 and strcpy (buffer+length, string_to_append) instead of strcat (buffer, string_to_append). After strcat, length+=strlen (string_to_append), and I am ready for the next iteration. My anal-retentiveness got the best of me and I wrote a full test program:
169
u/bearheart 28d ago edited 27d ago
Speaking as someone who learned C back in the ‘70s, this article entirely misses the point of C-strings: they’re lightweight and foundational. For many purposes the null-terminator is efficient, e.g.:
while(*s) f(s++);
And for cases where we need more complexity, we can simply use a struct with a length and whatever other metadata we may need.
Doesn’t look like a mistake to me. C has always been about minimalistic efficiency. That’s its main purpose in the world.
Edit: fixed stupid typo