Knowing C also helps me write more performant code. Fast Java code ends up looking like C code written in Java. For instance, netty 4 implemented their own custom memory allocator to avoid heap pressure. Cassandra also has their own manual memory pools to try to improve performance, and VoltDB ended up implementing much of their database in C++. I've been able to speed up significant chunks of Java code by putting my "C" hat on.
I would recommend every college student learn C, and learn it from the perspective of an "abstract machine" language, how your C code will interact with the OS and underlying hardware, and what assembly a compiler may generate. I would consider learning C for pedagogical purposes to be much more important than C++.
Do note that these are two very different things. The C abstract machine as defined by the standard is sometimes so different from the actual machines you're going to run your code on, that you get these fine undefined behaviour things that everybody's on about.
Please learn both, indeed, and stress the differences; then highlight the advantages of C. C is a dangerous, but powerful tool, and the necessity of warning students about things should not inhibit learning C.
C is sharp, yes. It's also a universal interface. Almost every language has bindings for C, and C has bindings for almost everything.
In my mind this is the #1 reason to learn C. And it's unlikely that C++ will replace C in this role anytime soon as C++ has many more ways for an ABI to go wrong.
Once whole operating systems are written in Rust maybe Rust will be the most important language but until then it's C. C++ doesn't really count. I don't think you can do any serious C++ without knowing C really well.
Really it wasn't too long ago that the STL just wasn't good enough for high performance code and we rolled our own containers/pooling/everything. Modern C++ is a very much a different beast these days.
I will say if you don't understand pointers you're in for a world of pain in C++.
This reads to me as if you ascribe those attributes to C, which simply isn't true; C++ has an equal (to C) concept of pointer, allocation/freeing (and, with RAII, I would argue superior).
Okay, but is that knowledge coming from coding in C, or it coming from debugging low-level code? I don't know what tool(s) you used to do that debugging, but if I assume for a second that you were using GDB, wasn't the main benefit of your past C experience (in this case) the exposure to tools like GDB, rather than your C knowledge being key in enabling you to dissect that JVM issue?
* How the code is executed on modern hardware and operating systems.
* How various language features might be compiled to assembly
* Memory layouts for things like stack frames, how a simple heap allocator might work, array layouts, layouts for other structures like linked lists, etc.
* The relative cost of various operations and how to write code that is cache friendly.
* How debuggers generally work and how to debug code.
Could these things be taught equally well or better in an undergraduate seeing using rust? Honestly I don't know; I know very little about Rust. I can say that I think C++ is a worse language for this purpose because of the language's complexity and because of features that aren't well suited for the above purposes.
I have heard, for instance, that's it's actually very difficult in rust to write a linked list without dropping to unsafe code. I would consider this a bad thing for the above purposes.
Does anyone know this at this point? With pipelining, out of order execution, vectorisation, register renaming, speculative execution, buffered micro-op fusing and what have you, it's very hard to say general things about how the code executes on the actual hardware.
I'm arguing that it's a matter of degree, not of kind. People make it seem like it's the latter.
Viewing all of code and data living together in a big array is important, I think. You don't understand e.g. dynamically generated thunks and shims without seeing the duality of code and data at the execution level.
Get your cache misses in order(which is easy to understand in the C model) and you're ahead of 95% of the curve(plus you get a 10-50x performance bump as a reward).
It is also hard in C to write a linked list without dropping to unsafe code. In fact, it is hard in C to add frigging signed integers without dropping to unsafe code.