Live data from Hacker News

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

words.steveklabnik.com

231–240 of 381 posts

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

#231

Earlier quoted context omitted.

Well... C teaches you how a PDP-11 worked, but modern computers aren't PDP-11s either. Most happen to expose a PDP-11-like structure via x86 assembly, but even that abstraction is a bit of a lie relative to what's going on under-the-hood. C doesn't let you write "string x = y" because it doesn't have string as a primitive variable type; that's the whole and only reason. It's not quite correct to say that "the compute…

> C doesn't let you write "string x = y" because it doesn't have string as a primitive variable type; that's the whole and only reason. But why does C not have string as a primitive variable type? It's for exactly the reason you state: there are very different approaches a high-level language can take wrt. string ownership/mutability. These approaches might require GC, refcounting, allocation, O(n) copies, etc -- ope…

I wouldn't call "lacks a feature" the same as "close to the machine" any more than I'd call "specifically refrains from defining whether 'a' or 'b' is first evaluated in an expression like 'a - b'" as "close to the machine." Machines lack statements and expressions entirely, but C has those; the reason that C refrains from being explicit on order of evaluation for (-) and other operators is that on some machines, evaluating b first, then a, then difference, lets you save a couple of assembly instructions at compile-time, and on some other machines, the reverse is true. So C's ambiguity lets the compiler generate code that is that much faster or terser on both machines (at the cost of, well, being Goddamn ambiguous and putting the mental burden of that ambiguity on the programmer ;) ).

Perhaps it is more correct to say not that C is "closer to the machine," but that C "tries to position itself as somewhat equidistant from many machines and therefore has design quirks that are dictated by the hardware quirks of several dozen PDP-esque assembly architectures it's trying to span." Quite a few of C's quirks could go away entirely if someone came along, waved a magic wand, and re-wrote history to make K&R C a language targeted exclusively at compiling Intel-based x86 assembly computer achitectures, or even one specific CPU.

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

#232

Earlier quoted context omitted.

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?

Addition, subtraction, and stack-relative addressing are, in most architectures I'm familiar with, generic- stack-relative addressing ends up just being a special case of register-relative addressing, and addition and subtraction are rather important instructions in their own right.

PUSH/POP are more obviously "hey store your locals on the stack, kids", but on, say, x64, how often do you actually see a push instead of bp/sp-relative addressing? Most compilers seem to be much happier representing each stack frame as "a bunch of slots, some for things where the address is taken so it needs to be in memory, and others where I spill things into as needed".

On ARMv7 (i don't know enough about v8 / AARCH64), "push"/"pop" are just stores/loads with postdecrement / postincrement.

Is this lawyer-y? Sure. But I think it's still correct, and this being HN...

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

#233
I teach C. It's an increasingly terrible way of learning "how a computer works". You would be much better off learning a little assembler.

The problem is most of the pain of learning C comes from undefined behaviour, which isn't how "computers work". The fact that depending on optimisation level writing past the end of an array might write to memory, or might not, is (mostly) a unique feature of C. Similarly sometimes a signed integer will overflow "cleanly", but then sometimes undefined behaviour will kick in and you'll get weird results. This (ironically) makes checking for overflow when adding integers in C annoyingly complicated.

With assembler if you write through a pointer, you write to that memory location, regardless of if you "should" be right now. You do multiplication or addition and you get well-defined 2s-complement wrap-around.

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

#235
post #75

Earlier quoted context omitted.

You can also learn that difference in something like C#. You don't need C for that. And C pretends there's a distinction between the stack & heap that doesn't actually exist. There is no significant difference there.

I suggest maybe you learn C :) or Rust. There are significant performance and strategy differences between the stack and the heap. On the stack, allocation is cheap, deallocation is free and automatic, fragmentation is impossible, the resource is limited, and the lifetime is lexically scoped. On the heap, allocation might be cheap or it might be expensive, deallocation might be cheap or it might be expensive, fragmen…

> On the heap, allocation might be cheap or it might be expensive, deallocation might be cheap or it might be expensive,

In other words it might behave just like "the stack"; the differences between different kinds of "heaps" are as large or larger than the difference between "the stack" and "the heap".

> fragmentation is a risk, the resource is 'unlimited', and the lifetime is unscoped.

None of these is true in all implementations and circumstances.

Understanding the details of memory management performance is important for particular kinds of programming. But learning C's version of "the stack" and "the heap" will not help you with that.

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

#236
post #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 mo…

I picked the CHAR_BIT example because it's very simple. I agree that it is not a major impediment to writing correct C today, most of the time.

One of my follow-up articles is precisely about the memory hierarchy...

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

#237
post #142

Earlier quoted context omitted.

I agree 100%, that was far and away the most valuable single class I took in college. We used the Tannenbaum book and a digital logic simulator, and worked up from basic gates into basic components (e.g. flip-flops and muxes, etc), then combined those into bigger components (ALU, registers, SRAM, etc), combined those into a toy 8-bit CPU, implemented cache and main memory, wrote an assembler that converted a small su…

>It was probably the hardest course of my entire degree, and I ended up taking it twice, Interesting. Did you study at a US univ.? I have not heard of being able to take the same course twice (except via, say, failing a year of the degree and having to repeat the whole year). I did hear that US universities are more flexible in some ways than, say, Indian ones, whose rules are probably based on British ones (maybe on…

I wasn't really ready to take it the first time (freshman spring...), and dropped it before the halfway point so I wouldn't take the hit on my GPA.

US colleges are all over the map with regards to how flexible they are about course order, and even between different degree programs at the same school. My alma mater had a somewhat weird trimester schedule and was relatively flexible about offering sections of courses year round - they had a bit of a housing shortage that made it impossible to house all the undergrads on campus at the same time.

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

#238
post #191

Earlier quoted context omitted.

> 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...

Yup. In compiled-languages land it's common to see things that are API-compatible but not ABI-compatible: the compiled objects don't work together, but if you recompiled the same source code it would work with no changes. This happens (sometimes) when you do things like reorder members of a structure or switch to a larger integer type for the same variable.

C and libc have been ABI-stable on most platforms for decades. C++ on some platforms (e.g., GNU) is stable with occasional ABI breakages in the standard library; on others (e.g., MS Visual C++) it breaks with new compiler versions. Rust isn't ABI-stable at all and has no clear plans for it, despite a strong commitment to API stability (i.e., old code will compile on new compiler versions). Swift 5 is targeting ABI stability.

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

#239
post #234

One thing I like about C is that it is a small language hence making it very approachable to newcomers. Other systems languages (C++ / Rust) have much longer roads to being productive.

What does "small language" even mean here? C has far more keywords, built in control flow constructs, and other special case builtins than, say, OCaml, so I'd argue it's actually a very large language. C's standard library is small but only because it's missing huge amounts of functionality (which might be acceptable in a language with a good dependency manager, but C doesn't have that).

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

#240
post #63

Earlier quoted context omitted.

But in addition to the mismatch between the abstractions provided and the real hardware, C qua C is missing a huge number of abstractions that are how real hardware works, especially if we pick C99 as Steve did, which doesn't have threading since that came later. I don't think it has any support for any sort of vector instruction (MMX and its followons), it doesn't know anything about your graphics card which by raw…

> A computer does not need to implement a stack C doesnt "have", or require, a stack, either. It has automatic variables, and I think I looked once and it doesn't even explitly require support for recursive functions.

You might be thinking of Fortran? C does require support for recursive functions.
Post reply on HN