It’s actually interesting to compare the pain and suffering of switching to a string datatype in the 80s (refactoring the limited code base then) vs the next 40 years of unnecessary boiler plate syntax and bugs for not having this type in key APIs.
But yes, the string slice type should have existed in C89 and it's very obvious from here that not having something of this sort - maybe what Rust would call &[u8] the reference to a slice of bytes - was a big problem for C.
The correct way to represent this is what's called a "fat pointer". A pair of values, one is a conventional "thin" pointer to the start of the slice, and the other is a count. Your register pressure increases in the compiler backend but problems are significantly reduced because you have fewer bounds misses.
That's a language design defect, C++ got its string slice reference (named std::string_view) only in 2017, years after Rust 1.0 shipped this as a core language feature, even though C++ is decades older.
On the other hand I can well believe on a 1970s computer where you'd be lucky to have 64kB of RAM the trade looks very different, I just think that by C89 it should have been fixed.
I guess Rust can keep slices safe using some borrow checker magic or something, but C++ can't.
If you keep const pointer to a std::string in C++ in 2016 that's exactly the same danger (of dangling pointers) as for a std::string_view in 2026, there's no change to that part.
That's not a bad thing, Common Lisp does the same and it Just Werks. The real problem is the more general "array to pointer decay", not arrays, really.