Except when it comes to cache, pipelining, registers, non-uniform memory access in general (not just cache), out-of-order execution and opcode pairing rules, SIMD architectures, and the existence of the processor status word. Other than that, yeah, C exposes you to a lot of worrying about memory allocation when algorithm design would be a better use of your time.
> other languages are easy peasy compared
The only way you could possibly say this is if the only languages you know are imperative Algol-derived ones with minimal type systems and no support for logic or declarative programming. Learning C doesn't make Prolog meaningfully easier. Learning C doesn't even make learning a mainstream language like SQL easier.
Understanding of the cache (specifically) and the memory hierarchy (in general), and of register allocation, are vital to writing efficient C code. Obviously, you don't have to understand that stuff to write marginal C code, but the idea that C hides it from programmers is a bit of a stretch.
I'm not sure what you mean by "the existence of a status word", since much of the expression syntax of C is a mapping of the status bits.
When I'm writing a bigint package in assembly, I can see whether the previous addition set the carry flag. In x86, I even have an adc opcode. There's nothing like that in C.
I would recommend almost anything with an interactive shell over a traditional C environment.
Python and irb are nice starting points because you can start out by claiming they are just a calculator, where you have to press return instead of =.
From there, you can go to variables (prevent you from having to type, e.g. the gravitational constant or a VAT percentage over and over), then to looping (print multiplication tables), to arrays (store them for later use, or as input for a loop to print year lengths for the planets, computed from their distance to the sun), and then to functions.
And all of that without having to teach people the difference between source, object code, and executable.
I agree that this is the case for casual programming. If you are teaching someone who has hardware experience (electrical engineer, etc), it is sometimes easier to build from the bottom up and C is as low as it goes without being assembly (a good and a bad thing).
For the low level stuff an assembly language is way better than C. C is still a LOT of magic that you won't be able to fully understand without understanding how the machine and the compiler works. In assembly a line corresponds to one instruction. What the assembler is doing is translating each line to an instruction number that the machine can interpret. That is a whole lot less magic than what happens in C. In addition, pointers are much easier to understand from a machine perspective than from a C perspective: they are just numbers indicating a location in memory. C makes that far too complicated with different data types, pointers to local variables (and higher up the call stack), confusing pointer declaration syntax, etc.
You can learn C syntax for assembly language idioms later. Starting out by learning the concepts plus the syntax at the same time leads to inefficient learning because when you're learning concepts like pointers it doesn't help to have to learn confusing stuff and syntax at the same time.
This does not apply to languages that cleanly abstract the machine like Scheme/Python/Haskell/what have you, but C lets the low level stuff shine through so much that you end up having to learn that anyway; you can't really learn it as an abstraction.
My first language was Javascript/Actionscript and then later Java. It wasn't until after that that I learned C and C++. But I agree that C should be one of the first languages learned.
> This still doesn't successfully counter the statement that C is the best language to start with.
I wasn't actually trying to refute that statement above; I was responding to the specific arguments used to support it.
Anyway, I agree with the other poster who replied to you: Pick a language with a REPL, as instant reinforcement of concepts is essential to ingraining them into the mind. Having a longer turnaround time means the lesson gets diluted by being interleaved with too much process (save the file, build the program, run it, look at the output, consider it, etc.).
> I don't understand how your comment is a refutation of the assertion that C will teach you more about the machine than other languages.
It completely hides some of the most important aspects of any modern hardware from you. The only thing it really exposes you to is manual memory management, and even then the view of memory C gives you is grossly simplified compared to how memory actually works on any modern hardware.
> Which language would you recommend using if you want to learn more about the machine?
Pick a machine and learn that machine's assembly language.
Except when it comes to cache, pipelining, registers, non-uniform memory access in general (not just cache), out-of-order execution and opcode pairing rules, SIMD architectures, and the existence of the processor status word. Other than that, yeah, C exposes you to a lot of worrying about memory allocation when algorithm design would be a better use of your time.
> other languages are easy peasy compared
The only way you could possibly say this is if the only languages you know are imperative Algol-derived ones with minimal type systems and no support for logic or declarative programming. Learning C doesn't make Prolog meaningfully easier. Learning C doesn't even make learning a mainstream language like SQL easier.