Once upon a time most Unix software was written in C, shell, and awk. Then Perl came along. Did that diminish C? No. Then Java. Did Java diminish C? No. Then Python. Did Python diminish C? No. (You can throw C++ somewhere in there; not sure where. Though IME C++ use really seemed to explode with Windows developers migrating to Linux.)
In each case the universe of software expanded, but C was never diminished. People who think Rust, Go, or whatever will diminish C are ignorant of history. Of course, maybe the predictions will bare out. But I seriously doubt it, and it will be despite their underlying premises, not because of them. Rather, much more likely is an expanded ecosystem.
As I explained else thread, there's nothing intrinsic to the C standard which makes it unsafe. Compilers are free to add bounds checking at every point in the program; in most cases it would be just as cheap as in C++ or even Rust. It would require much rebuilding and retooling, but not much rewriting existing software. (Relying on undefined behavior is dangerous not only because of optimizations, but because undefined behavior can also preclude automatic bounds checking.)
That C compilers don't do that is a function of 1) baggage and 2) other functional constraints, like strong ABI compatibility. But neither of those are set in stone. People who think C is hopelessly unsafe make the same mistake every C newbie (and some die-hard C-is-just-assembly people) do: conflating the language semantics with implementation and machine details.
People assumed that clang would quickly overcome GCC because it was so new and nimble. But clang still hasn't unequivocally really overtaken GCC, and certainly hasn't obsoleted GCC. Rather, the competition merely spurred GCC to evolve faster. I see much the same happening with C.
In the future, look to systems like OpenBSD, FreeBSD, and Alpine Linux, which are more free to upgrade their toolchain and runtime environments with backwards-incompatible changes, to field enhanced C environments with better bounds checking and mitigations. Approaches like stack canaries and ASLR are only the tip of the iceberg for what's possible.
> Compilers are free to add bounds checking at every
> point in the program; in most cases it would be just as
> cheap as in C++ or even Rust.
It would not be as cheap as in Rust because Rust uses an explicit standard library feature (iterators) to obviate the need for bounds checks in the vast majority of loops to begin with. But in C indexing is pervasive within loops, so you'd need to come up with much cleverer compilers that could manage to prove that bounds checks were unnecessary (compilers can already do this in some cases, for C/C++/Rust, but it's not perfect).Likewise, one could make integer overflow in C well-defined, but this would also make C slower than Rust because the use of iterators means that Rust doesn't need to check for overflow on each loop iteration. Via language (or rather, library) features, Rust reclaims the performance that it otherwise would have lost to C by dint of being free of undefined behavior. I think you'd have a hard time doing this in C without rewriting every `for` loop in existence.