Live data from Hacker News

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

words.steveklabnik.com

161–170 of 381 posts

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

#161
post #58

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…

C at the very least teaches the difference between stack and heap memory, a crucial concept obscured by most higher-level languages.

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 implement it with two instructions instead of one, and then you get as many stack pointers as you want. Zero, if you want.

There is no "heap" on modern OSes. There used to be a thing called the program break, beyond which was the heap. It's almost meaningless now. You ask for an area of virtual memory via mmap or equivalent; it is now one of several heaps you have.

And you can pass around pointers from all your stacks and all your heaps in the same ways, as long as they remain valid.

You need to understand this in order to understand how thread stacks work (you typically allocate them via mmap or from "the heap"); how sigaltstack works and why you need it to catch SIGSEGV from stack oveflows; how segmented stacks (as previously used in Go and Rust) work; how Stackless Python works; how to share data structures between processes; etc.

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

#162

Isn't the answer obvious? The inventors of C did apparently know how computer worked before there even was C.

not sure if you're trying to be facetious, but no, the answer is not obvious: it could have been the case that the creators of C decided to make it a faithful, thin abstraction aover the hardware of the computers they were using. In that case, learning how C works would tell you a lot about how that specific computer worked.

One point made in the article is that a) C wasn't really developed that way, and b) computers have changed considerably since then, so even the above was true, it no longer is true now.

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

#163

C teaches you how a computer works because the C abstract machine is defined such that operations that must be manually performed in assembly language must also be manually performed in C. C doesn't let you write something like: string x = y; ...because to actually create a copy of a string the computer must allocate memory, copy memory, and eventually free the memory. In C each of these steps is manual. Higher-level…

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 computer must allocate memory, copy memory, and eventually free memory" to do string assignment---it depends heavily on context and how a given language defines 'string' (are strings mutable in this language? If not, that statement may just be setting pointers to two immutable memory locations the same, and that immutability may be maintaned by type constructs in the language or by logical constraints in the underlying architecture like read-only TEXT memory pages---or both!---and so on).

The old Apple Foundation NSString is an interesting example of how the question of string manipulation is a complicated one that doesn't even lend itself well to the "allocate, copy, free" abstraction you've described. Pop that thing open, and you discover there's a ton of weird and grungy work going on inside of it to make string comparison, merging and splitting of strings, copying strings, and mutating strings cheap. There are multiple representations of the string attached to the wrapper structure, and a host of logic that keeps them copy-on-X synchronized on an as-needed basis and selects the cheapest representation for a given operation.

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

#165
post #141
post #58

Earlier quoted context omitted.

C at the very least teaches the difference between stack and heap memory, a crucial concept obscured by most higher-level languages.

> C at the very least teaches the difference between stack and heap memory, a crucial concept obscured by most higher-level languages. Go does that too. C teaches manual memory allocation, de-allocation and pointer arithmetic as well.

No, it doesn't. Go does escape analysis and allocates stuff on heap if needed.

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

#166
post #106
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…

> We spend a lot of silicon forcing our computers to "work like C does" (the specification for how registers work may as well read "we need to run C code very quickly no matter how much register renaming costs us in silicon" Can you elaborate? I thought I knew what register renaming was supposed to do, but I don't see the tight connection between register renaming and C.

Register renaming was invented to give assembler code generated from C enough variables in the forms of processor registers, so that calling functions wouldn't incur as much of a performance penalty.

The UltraSPARC processor is a stereotypical example, a RISC processor designed to cater to a C compiler as much as possible: with register renaming, it has 256 virtual registers!

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

#167
post #161
post #58

Earlier quoted context omitted.

C at the very least teaches the difference between stack and heap memory, a crucial concept obscured by most higher-level languages.

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…

For your definition of 'computer', perhaps. Many microcontrollers have the stack defined by the hardware.

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

#168
Technical nit: POSIX defines CHAR_BIT == 8 and on hardware where CHAR_BIT can be 16, 32 the alternative is to generate a lot of assembly (or just not work) to access 8 bits at a time.

In my opinion everyone should learn assembly in combination with a simple language to understand how a computer works.

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

#169
post #141
post #58

Earlier quoted context omitted.

C at the very least teaches the difference between stack and heap memory, a crucial concept obscured by most higher-level languages.

> C at the very least teaches the difference between stack and heap memory, a crucial concept obscured by most higher-level languages. Go does that too. C teaches manual memory allocation, de-allocation and pointer arithmetic as well.

No. In the machine model used by Go, everything is allocated on the heap. The optimizing part of the compiler can then move allocations from the heap onto the stack if it can prove that the allocation does not escape the lifetime of a stack frame.

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

#170
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…

Those performance and strategy differences only exist inside C or other high-level languages, as a result of abstractions created by those languages. They are not in any way reflective of "the computer."

By all means it's certainly a valuable abstraction, one that most high-level languages support. But that's like how functions are a valuable abstraction, or objects, or key-value stores, or Berkeley sockets. Learning those abstractions is absolutely important and also completely irrelevant to understanding "the computer".

(As Dijkstra once said, computer science is no more about computers than astronomy is about telescopes. Learning C is valuable for computer science, but that doesn't mean it gives you a deep understanding of the computer itself.)

Post reply on HN