Live data from Hacker News

Should you learn C to “learn how the computer works”?

words.steveklabnik.com

211–220 of 381 posts

Re: Should you learn C to “learn how the computer works”?

#211
post #191

C doesn't necessarily teach you how computers work. But it does teach you how software works. Our modern software empire is built on mountains of C, and deference to C is pervasive throughout higher-level software design. >You may have heard another slogan when talking about C: “C is portable assembler.” If you think about this slogan for a minute, you’ll also find that if it’s true, C cannot be how the computer work…

> Our modern software empire is built on mountains of C, and deference to C is pervasive throughout higher-level software design. This I agree with and also I'd call the most important reason for Rust programmers to learn C. The C ABI is a lingua franca, not because it's good or pure but (as with spoken linguas franca) happened to be in the right place at the right time. It defines certain conventions and assumptions…

For those who don't know what ABI means (as I did not) and thought it might be a typo.

ABI = Application Binary Interface

https://en.wikipedia.org/wiki/Application_binary_interface

https://upload.wikimedia.org/wikipedia/commons/b/bb/Linux_AP...

Re: Should you learn C to “learn how the computer works”?

#212
I'm afraid I found this a rather confused discussion of whether C will teach you "how the computer works". Yes, C is designed for an abstract machine -- all programming languages are, with the arguable exception of assembly language. Even with a language that perfectly modelled your CPU, you wouldn't learn "how the computer works" because the programming model presented by the CPU is itself an abstraction.* What's more important to my mind are the two major divergences between the hardware C was designed for and modern hardware, viz:

1. Massive changes to relative speeds of the memory hierarchy, and in particular the increasing divergence between near-CPU caches and system RAM. Nowadays it's often cheaper to recompute something rather than store it in memory. C is reasonable about letting you reason about this sort of thing, though, and

2. A major and increasing focus on parallelism for performance, which C is really bad at. Taking advantage of parallelism in C, particularly heterogenous parallelism such as clusters and GPUs, is a real pain. Classic example: the PS3 "Emotion Engine"; more modern example: graphics and physics coprocessors and CUDA. At the other end of the spectrum we have languages like Futhark where your code will be equally happy on a CPU, GPU, or both.

Compared with these major issues the differing size of char, say, is kinda irrelevant. Yes, CHAR_BIT >= 8 is not how the computer works, but that's not really a fundamental issue in the sense that -- well, in the sense that you can quite easily learn C thinking that CHAR_BIT always equals 8, and then update your knowledge relatively quickly. It's a small and modular piece of knowledge in the same way that, for example, updating your mental model of programming to include parallelism is not.

* This seems like a trivial point, but it's not -- actually understanding what's happening with your program may involve understanding DMA, the way buses are organised on your system, the way IRQs work, cycle timings, and on and on. The best you can hope for at the PL level is to have a reasonable high-level idea of what the CPU (or at least a single core) is actually doing, and C is still relatively good at this.

Re: Should you learn C to “learn how the computer works”?

#213

Earlier quoted context omitted.

Thank you! > if your goal is just to get familiar with that region of the continuum and not become an expert in a new language, C has a good price/performance ratio. I think this is a particularly great point in your post. I wonder what AndyKelley thinks of this, as in my understanding, that's sort of what Zig is trying to do as well. That is, Zig is attempting to be a language on a specific spot on the price/perform…

I agree with this characterization. Zig is trying to directly replace the niche that C represents, in terms of exactly this tradeoff. So if Zig is successful, in 4 years the title of this post would have been "Should you learn C/Zig to 'learn how the computer works'?" and in 8 years the title would have been "Should you learn Zig to 'learn how the computer works'?". :-)

Excellent :)

Re: Should you learn C to “learn how the computer works”?

#214
post #186

One valuable property of C that the author didn't hit, C code is easily translatable into assembler in your head. He kind of misses this point with the virtual machine discussion. Yes C code becomes different types of assembly by platform, but you can look at C and have a clear idea of what the assembly will look like. This is at a really good level for driving intuitions about what the computer is actually doing. Yo…

> Yes C code becomes different types of assembly by platform, but you can look at C and have a clear idea of what the assembly will look like.

Not anymore, with modern optimizing compilers it's hard to reason about -O3 assembly output.

https://godbolt.org is amazing to play with that

Re: Should you learn C to “learn how the computer works”?

#215

Earlier quoted context omitted.

I think I may miss your meaning. In what sense is .size or length() not "free?" At some point, some O(n) work was done somewhere to construct the n-element structure we're getting size on, but I don't think I've ever encountered a core library that implements .size as anything other than "Look up the cached length value that I computed the last time my length changed."

C strings do not have a cached length. This is one of their largest weaknesses, which is why many other languages do not use C strings.

Oh. Right.

I think I just gave away the game on how long it's been since I programmed in C itself. Even C++ has "free" length() in std::string (in the sense that it's specified that it must be a constant-time operation).

... that's actually a good example of the trap of thinking of C as "what's really going on." If you assume C's treatment of char* is how strings have to be done, you're out of alignment with basically all other programming languages and you might be writing unnecessarily slow code (or forcing developers using your code to juggle a homegrown "length" abstraction that the underlying language should be juggling for them).

Re: Should you learn C to “learn how the computer works”?

#216
post #161

Earlier quoted context omitted.

There is no difference inside the computer between those concepts. For convenience, many architectures have a single assembly instruction for taking one register (called the "stack pointer"), adjusting it by a word, and moving a register to the address at that word, and a corresponding instruction to move data back to a register and adjust it in the other direction. That's the extent of the abstraction. You can imple…

I think this is lawyering a bit. There might not be a "heap", per se, but there is stack allocation (which is embedded all the way into the ISA) and "everything else". You can, after all, build a simple "heap" on top of an adequately large static buffer. Since this is a distinction that is very important both for performance in high-level languages and for correctness in C, and one C forces you to think about and mak…

Stack allocation of return addresses is embedded in most ISAs- but stack allocation of local variables isn't (because that's not A Thing at the ISA level).

Consider, say, shadow stacks- local variables might end up living on a totally separate "stack" from the one "call" pushes onto and "ret" pops from, and one which the ISA has no idea about.

Re: Should you learn C to “learn how the computer works”?

#217
post #205
post #186

One valuable property of C that the author didn't hit, C code is easily translatable into assembler in your head. He kind of misses this point with the virtual machine discussion. Yes C code becomes different types of assembly by platform, but you can look at C and have a clear idea of what the assembly will look like. This is at a really good level for driving intuitions about what the computer is actually doing. Yo…

> One valuable property of C that the author didn't hit, C code is easily translatable into assembler in your head. He kind of misses this point with the virtual machine discussion. Yes C code becomes different types of assembly by platform, but you can look at C and have a clear idea of what the assembly will look like. I've seen this many times, I'll be honest: I can write C, but for the life of me I don't have the…

Same here.

At one point, I probably could've looked at C and had a pretty clear idea of what the 68HC12 assembly would look like... but I've never bothered to learn x86/x64 assembly, or ARM assembly, and I've written way more C code for those architectures than I ever did for microcontrollers back in undergrad.

Re: Should you learn C to “learn how the computer works”?

#218

Earlier quoted context omitted.

I’m convinced that Forth is a valuable intellectual exercise. Can you elaborate on how you feel Forth better matches how a computer actually works? I’m not yet convinced on that point, but I have no Forth experience.

The most fun, in a tinkering sense, that I've ever had with low level programming was in a variant of Forth (within Minecraft, years ago when the mod that included it was still up to date). That experience made me regret that Forth wasn't part of my formal education experience: it is a wonderful slightly above assembly language. Forth is what should be included in a BIOS as the absolute lowest level interpreted langu…

I'm not sure if you're posting this with awareness, but for the public benefit I'll say that this had been done, ages ago indeed.

https://en.wikipedia.org/wiki/Open_Firmware

I've had the pleasure to interact with it while trying to get a SPARC Ultra 60 workstation to work. The driver hooks missing from most modern hardware meant that not all graphics cards could be used with full support - currently BIOS drivers provided on some PCI hardware (RAID, network adapters) are only for the x86 architecture. I forgot what they are called though...

Re: Should you learn C to “learn how the computer works”?

#219

C doesn't necessarily teach you how computers work. But it does teach you how software works. Our modern software empire is built on mountains of C, and deference to C is pervasive throughout higher-level software design. >You may have heard another slogan when talking about C: “C is portable assembler.” If you think about this slogan for a minute, you’ll also find that if it’s true, C cannot be how the computer work…

> Our modern software empire is built on mountains of C, and deference to C is pervasive throughout higher-level software design.

this is the key. If you want a real-world view into how the kernel is written (i.e. more of the computer), then C is the only practical choice. Sure, you can write an OS in Java, Haskell, OCaml, etc. But it's roundabout. So, I think the statement, "learn how a computer works more by leveraging C" is valid.

Re: Should you learn C to “learn how the computer works”?

#220

Earlier quoted context omitted.

I think this is lawyering a bit. There might not be a "heap", per se, but there is stack allocation (which is embedded all the way into the ISA) and "everything else". You can, after all, build a simple "heap" on top of an adequately large static buffer. Since this is a distinction that is very important both for performance in high-level languages and for correctness in C, and one C forces you to think about and mak…

Stack allocation of return addresses is embedded in most ISAs- but stack allocation of local variables isn't (because that's not A Thing at the ISA level). Consider, say, shadow stacks- local variables might end up living on a totally separate "stack" from the one "call" pushes onto and "ret" pops from, and one which the ISA has no idea about.

In what sense is stack-relative addressing, PUSH, POP, and addition/subtraction on the stack pointer not ISA-level support for stack allocation of local variables?
Post reply on HN