You're quite correct in saying that none of those things are true but you're wrong in saying that these are "the proposed benefit" of C. I feel that's a common misconception really.
A huge advantage of C that most people seem to forget these days is that it's quite a minimalist language by today's standards so it's relatively easy to learn and reason about.
But maybe the most compelling advantage is that its underlying architectural concepts map well to most real-life CPUs so it's a much better basis for compilers to generate efficient code than many languages. This is a subtly different thing from being "close to the metal". It's really more like "has compatible design concepts with CPUs". The abstract machine of C has relatively few gotchas when converting to machine code and that's what it's really about.
That doesn't mean that C's the "high level assembler" people speak about though. It's not. Take a look at some optimised assembler output from a C compiler and you'll see that's patently not true. It can be very difficult to even understand how the C source code relates to the generated assembler code - often you'll see that none of the same operations occur and nothing happens in the same order.
C is easy to learn but not to reason about. First of all, C is really C + macro-C, two separate languages that don't know about each other. Second, all the damn UB. Third, weak typing and fourth, memory errors. So no, reasoning about C is far from easy.
These arguments sound like the arguments of someone who hasn't programmed much in C. C's undefined behavior is a non-issue in almost any realistic programming situation - it would only normally crop up in cases where you're deliberately doing something strange like overflowing a variable. The typing is a non-issue if you don't do stupid things. Memory errors can be an issue but tools like valgrind make them a relatively minor hassle. None of these affect your ability to reason about C, at least not as a normal programmer.
...can easily happen indeliberately. Just as any other exceptions. Which C can't even handle in a deterministic way because it doesn't have built-in exceptions, so you have to rely on libraries or remembering to check error codes. Not easy to reason about.
> typing is a non-issue
When all your function ptrs have to be cast to and from (void*) - hell yeah it's an issue.
> minor hassle
Then why are buffer overflow exploits in C programs on the news?
A huge advantage of C that most people seem to forget these days is that it's quite a minimalist language by today's standards so it's relatively easy to learn and reason about.
But maybe the most compelling advantage is that its underlying architectural concepts map well to most real-life CPUs so it's a much better basis for compilers to generate efficient code than many languages. This is a subtly different thing from being "close to the metal". It's really more like "has compatible design concepts with CPUs". The abstract machine of C has relatively few gotchas when converting to machine code and that's what it's really about.
That doesn't mean that C's the "high level assembler" people speak about though. It's not. Take a look at some optimised assembler output from a C compiler and you'll see that's patently not true. It can be very difficult to even understand how the C source code relates to the generated assembler code - often you'll see that none of the same operations occur and nothing happens in the same order.