> A name like strlen suggests that it's designed to take the length of a string
It is. A "string" in C is a char[] (there is no "string" type). A char is a type that is a number. That number has no meaning aside from being a number. Conveniently, you can assign a char like so:
char foo = 'b';
That sets the variable foo, of type char, to the value 98. That the 98 means anything, in particular, the letter 'b' in many character sets, is a complete accident and completely orthogonal to char's purpose. A "string" in C is a collection of chars. That is all. No encoding (especially not "the shrine of ASCII"), no purpose beyond being an array of numbers that end in 0, just a bunch of numbers.
You are misunderstanding "strings" in C, and by extension, strlen(). This is not a problem with UTF-8. This is a problem with you misunderstanding the C library and basic types. If you don't believe me (I'm right, but, your call), you can certainly download the C99 spec and investigate what a "char" is, what a "string" is (hint: there isn't such a thing at all), and what "strlen()" is designed to be.
Here's a simple, naive strlen():
size_t strlen(char *string) {
char *p = string;
while(*p) p++;
return p - string;
}
That's it. No "monotheism at the shrine of ASCII". It counts
chars until it finds 0. It is giving you the right answer. That you don't understand the answer is not UTF-8's (or C's) problem at all. Now, if you want to talk about printf(), I'm listening -- because you might be able to conjure up a point there -- but you are not talking about printf(). This, and other comments, are way off-base on how strlen() works.
> Null is valid UTF-8, it just doesn't work with C 'strings'.
Sure it does! I can store a null in a char[] all day long. That just changes its behavior when passed to something that counts the length of a char[] before a terminating null (like, wait for it, strlen()). Watch!
char buf[8];
buf = "abcde\0f";
What we have here is a buffer of length 8, which contains these char values:
97 98 99 100 101 0 102 0
Now, strlen(buf) is 5. That's because
that's what strlen is designed to do. The actual length of the buffer is, amazingly, still eight, and if your code expects to work with all eight chars in the char[], then by golly, it can.
If you are using strlen() with any expectation of character set awareness or human alphabet behavior, you completely misunderstand the purpose of strlen().
Since you're so adamant that UTF-16 is better (but you completely misunderstand how C's typing works), I'm less inclined to accept your opinion on UTF-8 being a "massive hack". Explain to me what strlen() on a buffer containing a UTF-16 string does -- and, why that's better -- and I might come around.