Hacker News new | ask | show | jobs
by yetihehe 842 days ago
> While I agree with last two paragraphs, C is not good even for that purpose because it doesn't give any tool to manage them.

That is the reason it should be used as a learning tool. So that you know the nitty gritty details without anyone "managing" it away from you.

1 comments

Then learn an assembly language instead, because C also has a fair amount of bookkeeping hidden behind the scene.

C is typically described as a "low-level" programming language, where the "low-level" normally refers to the supposed distance from the language to the actual hardware. But as many incidents with UB demonstrate, this distance is still quite larger than expected. I think there is another sense of the word "low-level", which is the amount of abstractions that are either built into the language or allowed for users, and C doesn't have a lot of them.

Combined together they represent related but distinct axes of controllability, and C only achieves a modest level of controllability in one axis but not in another. The ideal language with controllability in comparison should minimize the distance to the machine and maximize an amount of abstraction to control anything below the language instead.

> Then learn an assembly language instead

Learn assembly TOO, not instead. I did, as part of computer architecture course. Very valuable. I think you should learn everything from transistor level up if you want to do serious programming. I don't think you need to actually use it, but it's sometimes very handy to know those things.

It's important to set a correct expectation for what you learn. C is indeed important to learn because of all legacy and current code bases, but it's just one of possible language choices for learning computer architecture, and learning C alone doesn't give you a relevant knowledge.
> C also has a fair amount of bookkeeping hidden behind the scene

Hosted C does in the form of the standard library. C does have a freestanding variant though and its book keeping is generally limited to knowing struct member offsets.

This is mostly only true for modern optimising C compilers. If you take a simple C compiler from the 90's, or disable optimisations in a modern compiler, there's a near 1:1 relationship between the C code and compiler output.
Yes, but I don't think you necessarily argue for using those simpler compilers today.
Of course not, but it might explain where the idea comes from that "C is high level assembly". Apart from that, I think every programmer should play around with godbolt at least once in a while to get an idea how the high level source code maps to machine code. Even with optimizations enabled, the output of C code is usually much closer to the source (e.g. more "recognisable") than (for instance) highly abstracted C++ or Rust code.
> Even with optimizations enabled, the output of C code is usually much closer to the source (e.g. more "recognisable") than (for instance) highly abstracted C++ or Rust code.

That's usually true, but you can write C++ and Rust codes that more closely map to machine code as well. Most C code exhibits that only because you can't have enough abstractions to disrupt that mapping. It is good when you do need that kind of correspondence, but most applications rarely need them, and even performance-sensitive applications don't need them all the time. C does give you a knob, but that knob is stuck in a lower but not lowest position.