Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

C is a leaky abstraction based on a simplified model of how computers and their memory worked in the 1970s. C code is transformed in complex and heavily context-dependent ways by all but the most primitive compilers before it hits metal, despite the popular opinion that "the language is close to the machine".

If you like C, use it. If you want to know what's going on, learn assembly.



You're conflating the language with its modern compilers on modern processor architectures, but I agree. My statements above were the iconoclastic and anachronistic version of reality, purposely so.

If you know C, it is possible to comprehend a direct mapping of your "high level" code to a set of processor instructions. This is complicated by modern huge glib-style libraries and modern compiler optimizations, but it remains possible.

That, combined with the fact that C is foundational in almost all current production languages, and remains highly useful among them, are why I think anyone who takes programming seriously should know C.

Someone else compared C to Latin. Obviously C is more useful on its own than Latin, but the comparison is valid for the foundational aspect. Understanding threads and locking in C gets you a long way toward understanding those concepts in most popular languages.

I'd make the same arguments for understanding Unix, by the way...and also that you can't really understand Unix without understanding C. And the converse.


> This is complicated by modern huge glib-style libraries and modern compiler optimizations, but it remains possible.

I disagree. It's complicated by those things, but more importantly it's complicated by modern processor architectures, which do not execute one instruction after another anymore like C would have you believe - they just mostly pretend to.

Which isn't to say this is any less true of the other high-level languages we have at hand, and I still think knowing C is valuable (although I'm wavering more on that then I was 5 years ago), I just think your characterization is incorrect.


OK, but you're diving deep into arcane abstraction there. All the tricks that modern processor architectures do for speed are only relevant to your understanding if you are designing microprocessors (which everyone should also try, we did it in college, and it was a blast).

At that level, even the compiled opcodes aren't strictly demonstrative of what's happening inside the processor, but you'd only know that if you were running a simulator and watching traces light up.


Well, that's a part of it but it can be relevant to performance. Cache behavior and branch prediction aren't very visible in C. There's also a lot of goings on with memory where C just says, "Uh, unspecified!", particularly with multiple cores and/or cpus.


Yes and no, there are no way in plain C to excert direct control of branch prediction or cache usage, however that's where GCC extensions come in.

Extensions such as __builtin_prefetch, __builtin_expect are heavily used in the Linux kernel to allow a higher level of optimization by directly instructing the compiler how to handle branch prediction and caching (based upon careful benchmarking) in performance critical areas rather than leaving it up to the compiler's 'compile-time' heuristics.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: