For instance, if you copy a string you also have to update the end pointer instead of just copying the size attribute in bulk. And you get the same disadvantages of non-portable strings, different representations depending on the architecture/endianess etc...
I completely agree with the OP, there's no perfect solution. If addr + len was truly superior I'm sure we'd see
struct string { long len; char s[]; };
or for your version struct string { char *endptr; char s[]; };
everywhere. And the C standard library would have evolved along with it.Out of the top of my head the only thing that makes '\0' terminated strings special in C is that it's the way string literals are represented. It would be trivial to recode all of string.h using addr + len instead of nul terminated.