Let me rephrase. You say C is simple. I say Rust (for example) is simple. I can look at a Rust code base and say confidently - this code base has no UB in it, it has no memory safety issues in it.
Can you look at a non trivial C code base and make such an assertion? You can’t. Even simple looking C code could be translated into problematic assembly because such a transformation is technically valid. And it’s beyond the ability of anyone but an expert to guard against that.
C is a very useful language. Very important. Very fast. A great tool in the right hands. The world wouldn’t run without it. And it will remain useful and important and fast for decades to come, certainly. But it’s not simple and hasn’t been for a long time. Let’s acknowledge that.
I'm sorry I don't understand your argument at all. What does lack of UB and memory safety have to do with simplicity? Those are very complex features of Rust which require a very complex compiler in order to achieve. Also Rust is notorious for having a steep learning curve, and it takes time for even very experienced programmers to become accustomed to it.
1. The compiler isn’t doing anything unusual or unexpected. It applies only basic, easily understandable transformations from C to assembly
2. An intermediate C programmer would be able to guess correctly most of the time what the generated assembly would look like. And thanks to this, such a programmer would be able to avoid most footguns.
But the compiler does unusual/unexpected things, and it’s hard to guess what assembly will be generated or what that assembly does, it’s not a “thin abstraction”. Would you agree?
I don't think this is the best way to understand this. C has been around for 50 years at this point, and there has been an enormous amount of investment and advancement in the realm of C compilers in that time, which has naturally resulted in complexity and esotericism in terms of how actual mainstream C compilers work. But that's not a metric of language complexity, it's an artifact of a half century of work on the topic.
I think a better metric is: an average CS grad with a little bit of background in compilers and assembly could reasonably be expected to be able to write a naive C compiler which covers say 80% of the footprint of the core language on their own in a matter of weeks.
What do you think is the size of the cohort of people who could write a naive Rust compiler, with borrow checking, ADT's, traits and non-lexical lifetimes? Even without some of the fancy bits like async you're already talking about grad level CS topics at the very least.
Can you look at a non trivial C code base and make such an assertion? You can’t. Even simple looking C code could be translated into problematic assembly because such a transformation is technically valid. And it’s beyond the ability of anyone but an expert to guard against that.
C is a very useful language. Very important. Very fast. A great tool in the right hands. The world wouldn’t run without it. And it will remain useful and important and fast for decades to come, certainly. But it’s not simple and hasn’t been for a long time. Let’s acknowledge that.