> For one thing how big (sizeof) should the length prefix be? 16-bits? 32-bits? 64-bits?
size_t, or uintptr_t [1]. Maybe uint32_t, although given pointer alignment, smaller-than-pointer for size doesn't help all that much.
> The beauty of the C string is that it is minimal and straightforward: if you have a pointer to it, you know where it ends.
And if you screw up adding a null byte, client code will happily keep running through the rest of memory to find it. And if your string has embedded nulls, you're SOL anyways.
> And it works with pretty much any OS out there.
And for safety reasons, the OS generally has to assume a maximum length anyways, otherwise, you tend to have security vulnerabilities.
[1] size_t is not necessarily the same size as uintptr_t. An architecture with a 64-bit base pointer shared across several 32-bit indexes is an interesting idea that could use some more programming exploration.