4 ms·
I agree John Regher's take on teaching C: http://blog.regehr.org/archives/1393 http://blog.regehr.org/archives/1393 In summary, it's a useful skill to have but
by noelwelsh 10y ago
I agree John Regher's take on teaching C: http://blog.regehr.org/archives/1393 http://blog.regehr.org/archives/1393 In summary, it's a useful skill to have but you're not doing your duty as an instructor if you don't make your students aware of its many shortcomings.
I particularly want to take issue with the claim in the original post that "C helps you think like a computer". C's machine model might have been a good model for the machines at the time at which it was developed, but it hasn't been an accurate model for a long time. A simple example is C's assumption that memory is flat and all locations have an address. With multiple layers of caching and nearly a couple hundred registers in current CPUs this is far from the truth. If you think programming in C is programming at the machine level you are deluding yourself.
- m_mueller 10y agostill better to have some concept on how memory works though, even if it's still an abstracted version of what happens on the machine. If all you ever see is Java or Python, the mental step to understanding memory optimization and caching becomes much larger.
- bluetomcat 10y ago> With multiple layers of caching and nearly a couple hundred registers in current CPUs this is far from the truth. Add to that the aggressive optimisations performed by modern compilers and that mental model breaks completely. It may be a good conceptual model, but it's not the model under which your program actually executes. However, even programming in assembly keeps you very "far from the truth", since modern CPUs are very complex beasts internally and that complexity is mostly not visible in the ISA.
- sigjuice 10y agoYup. Caches, prefetching, NUMA, out-of-order execution, speculative execution etc.
- planteen 10y agoThe thing about speculative execution and out of order execution to remember is that you always get the expected result from a single threaded perspective. If you throw in interrupts or threads, you know you must tread cautiously in C. Few things have made me more nervous in my career than seeing a ISR making use of C++ standard library features. When I asked the engineer how they were sure this was safe and worked under the covers, I was immediately dismissed as "the compiler takes care of all that." The project only ever worked at -O0 and was still buggy. The engineer blamed the hardware.
- johncolanduoni 10y agoYou're right as far as results, but both can still mess significantly with performance even when everything is single threaded.
- vkuruthers 10y agoAhh, blaming the hardware. A sure sign they haven't looked into their code closely.
- claudius 10y ago> The thing about speculative execution and out of order execution to remember is that you always get the expected result from a single threaded perspective. Could you elaborate on this? I thought at least speculative execution was handled internally in the CPU and essentially not visible to the user apart from the performance impact? I’m not sure what you refer to as out-of-order execution, is this execution reordering within the C compiler? > If you throw in interrupts or threads, you know you must tread cautiously in C. Naturally, yes.
- winter_blue 10y agoThe x86 instruction set (and other instruction sets), abstract away much the underlying hardware architecture. The "flat memory" abstraction originates from and is presented by most CPU instruction sets -- C just tries to be as close to a "generic" assembly language as possible. I wonder when we'll get an instruction set that gives us fine-grained control over the different levels of caching, or even the ability to create FGPA-esque microcode functions, etc. Compiler writers could have the time of their lives with such an ISA.
- noelwelsh 10y agoI think with today's CPUs a generic assembly language would at least make a distinction between registers and memory locations. Programming with a conceptually infinite number of registers would be fairly simple and should make reasoning about memory locality easier. Current x86 CPUs have 192 registers internally, so you'd almost never go outside the register file unintentionally. I'm not very experienced with GPU programming, but my understanding is that the programmer has more control over memory locality there. Another point to remember is that CPUs have coevolved with programming languages. I think if languages tried to expose more detail in their machine model, ISAs might evolve to match this. Finally, hardware designers mostly aren't programming language people, and programming language people generally haven't been interested in languages in the same space as C (though that is changing.)
- telotortium 10y agoCPUs had registers back when C was invented too :) The reason C doesn't expose registers is because the flat memory model is more universal and more uniform between CPUs than the registers, which often have a lot of special-case behavior, especially on non-RISC CPUs: https://vanemden.wordpress.com/2016/03/15/why-does-c-not-have-an-exponentiation-operator-2/ https://vanemden.wordpress.com/2016/03/15/why-does-c-not-hav.... Besides, C has a "register" keyword, although it's probably ignored by almost all compilers today in favor of their own optimizations, which are usually better (and if they're not, you're usually gonna go to assembly for maximum performance anyway).
- drvdevd 10y agoI think you're definitely correct but it begs the question: is there another modern language that does help one get "closer to the machine" conceptually in a correct manner?
- morty16 10y agoAmen. Further, C helps you think like a particular evolutionary path of computer, and the language and architecture developed mostly in parallel. It's like saying that giraffes have long necks because they need them to reach the tall branches.
- joveian 10y agoThat is a great post on teaching C. I think there are a couple of ways that it could be argued that "C helps you think like a computer": most CPUs have been designed around running C code quickly and the oddities of the language force you to think like the compiler (which has both positive and negative aspects :/ ). For that matter, things like UNIX and POSIX make more sense if you underderstand C (and vice versa) and there are multiple complete and fairly popular open source operating systems you can examine that are written in C (and the mailing lists of these operating systems can be excellent places to learn a bunch of low level stuff). On the negative side (as you mention), I think it is very common to think of C as a lower level language than it really is (I'm planning on learning Ada, which it sounds like has more low level features, although still not the same as learning CPU architecture). C forces or encourages you to learn a lot more about everything than other languages, which not a great thing if you just want to write a reliable program but isn't such a horrible deal if learning such things is part of the point. D, Ada, and to a lesser extent Rust seem similar in some respects and with significant benefits but without the easily accessible operating system projects (so far, that I know of). So I guess my addition to that excellent post would be that if you are going to learn C you should get involved with an OS project. The BSDs are particularly good for this due to being more integrated systems and slower moving with more design consideration given to new features than in Linux. I'd personally recommend NetBSD, where the tech-* mailing lists are high quality and fairly low volume, but any of them should work well.
- steveklabnik 10y agoThere's actually a very strong hobby kernel chunk of the Rust community, and it's fairly education-focused. http://os.phil-opp.com/ http://os.phil-opp.com/ kicked it off, and my own project based on it, http://intermezzos.github.io/ http://intermezzos.github.io/ is coming along. There's also more serious efforts: https://www.redox-os.org/ https://www.redox-os.org/ has made tremendous progress in a relatively short period of time, https://robigalia.org/ https://robigalia.org/ is an extremely interesting effort for Rust on top of seL4.
- joveian 10y agoVery cool, although not yet the same as well established production operating systems. I think Rust will be a great alternative to C in a decade and worth considering even now. In case it wasn't clear, my "to a lesser extent Rust" comment was just about my impression that Rust can more easily be used without worrying about optimization level details vs. D or Ada or C. Which is a good thing if true since Rust can also deal with the low level stuff, although possibly it is just my mistaken impression (I only actually know C out of these languages).