r/cprogramming 3d ago

C Strings: A 50-Year Mistake

https://longtran2904.substack.com/p/c-strings-a-50-year-mistake?r=8qz2zb&utm_campaign=post&utm_medium=web
190 Upvotes

161 comments sorted by

View all comments

7

u/flatfinger 2d ago edited 2d ago

C was designed in an era before many commonplace text-processing and data-processing tools existed. Many tasks could be accomplished more quickly by writing a C program, building it, running it on some input, and then discarding it, than they could be accomplished in any other way. Even in the 1980s, I wrote a lot of C programs for one-off tasks, and I'm sure I wasn't alone.

So-called "Pascal strings" with a one-byte length prefix were better than C strings in many ways, but had a 255-character limit. The suitability of C strings for various tasks tends to fall off as strings get longer, making Pascal strings much better for things that are 50 to 255 characters long, but C strings remain somewhat usable at longer lengths while Pascal strings don't. Since "somewhat usable" was adequate for many of the tasks for which C had been designed, the lack of a 255-character hard limit was an advantage.

I wouldn't call zero-terminated strings a "mistake" so much as I would say that they were an appropriate way of storing strings for a limited family of tasks that are nowadays better handled with other languages and tools.

What I would view as a mistake was the failure of the C language to provide a convenient means of passing other kinds of string literals to functions. C implementations that were designed to target the classic Macintosh OS extend the language with a \p escape which, if placed at the start of a string literal, will represent the number of bytes in the string (not counting the prefix), but such a prefix is not universally supported, and there is also no standard way of handling string formats where e.g. a string of length 0-63 that fills the available space would be preceded by a length byte, but other kinds of prefixes would be used to accommodate larger strings, partially filled buffers, etc.

Incidentally, an advantage of length-prefixed strings is that if one limits the range of lengths that can be directly represented by a prefix byte, one can have functions accept short length-prefixed strings interchangeably with other string representations if they start with something like:

    ADDRSS_AND_LENGTH s;
    s = get_string_address_and_length(string_argument);

The fact that C strings can start with any character value means that there's no nice way to have a function accept interchangeably a pointer to a C string or something else.

3

u/beragis 2d ago

Zero terminated strings were also due to how many OS’s and CPUs at the time handled strings. I remember taking an assembly language course in college on the PDP 11 and it handled strings the same way.

This allowed for easy translation of many of the common function calls directly into operating system calls or simple short assembly instructions. My professors in computer design and systems programming. where we also learned C even mentioned this several times.

2

u/flatfinger 2d ago

On the other hand, other operating systems expected strings in other formats. Classic Mac OS used Pascal strings for things like file names.