Yeah, I simply avoid them. I used macros and tiny structs to track length. In noscrypt I replicated C# spans with inline functions and small structs, the same way literally every other language does because most of them are written in C anyway lol.
To be fair though, if people didn't keep ignoring the language requirements, ub, and ignoring compiler manuals, storing the termination with 0 at the end of a buffer is arguably the most efficient way to handle that. Strings are just a sequence of memory, and literals are stored in data segments. Most efficient way to handle that imo.
https://git.vaughnnugent.com/cgit/vnuge/noscrypt/.git/tree/src/nc-util.h#n96