Live data from Hacker News

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

words.steveklabnik.com

201–210 of 381 posts

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

#201
post #106

Earlier quoted context omitted.

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

Register renaming is older than C (the first computer with full modern OoOE was the 360/91 from 1964). It has more to do with scheduling dynamically based on the runtime data flow graph than anything about C (or any other high level language).

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

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

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 makes plain without having to reason through escape analysis and closures, I think the previous comment's point is well taken.

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

#203
post #188

Earlier quoted context omitted.

Our popular software stacks are written in C and C++, but that's more because of history than anything else. I rarely reach for just "classic" C for performance anymore. These days I'm more likely to reach for GPUs, SIMD intrinsics (available in Rust), or at least Rust/Rayon for code that needs maximum performance. C is fundamentally a scalar language. In 2018, the only code for which "classic" C is the fastest is co…

Are you promoting Rust on every topic about GC / performance topics?

Rust is fundamentally a scalar language too. If anything, I'm promoting vector languages like GLSL/Metal/etc.

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

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

Here's the C99 standard:

http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf

There are no occurrences of the words "stack" or "heap" in this document.

What the spec actually discusses is "storage durations". Now, in many cases you can say, well, "automatic storage duration" means it's on the stack, but that's not something C has any opinions about.

If you want to know about the stack and the heap, saying "learn C, and then learn how these abstract C concepts map onto the stack and the heap" might not actually be the best way to figure this stuff out.

What actually ends up happening, in my experience, is that to figure C out you have to get a decent mental model of how the stack and heap work, and then, from that, say "automatic storage duration and malloc/free are basically just the stack and the heap".

I learned calculus as a kid because I needed it for an online electronics class I was taking. But I'm not going to recommend that folks take electronics classes so they learn calculus! (that said- having a motivation to learn something, having an application in mind, a problem you want to solve... certainly seems to make learning easier.)

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

#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 slightest clue how the assembly code will look like.

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

#206
Back in the day, people told me that after learning C, learning anything else about programming would be much easier.

I think I understand now. C hits a sweet spot between high and low level programming, allowing you to unobstructedly move either up or down the abstraction hierarchy.

Transforming a piece of C code to machine instructions in your head is manageable, and so is transforming high-level abstractions to C code.

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

#207

Earlier quoted context omitted.

We have our differences, but you’re totally correct here, and I’m not sure why you’re downvoted. The “byte addressable” thing is exactly why C was created over B, even, right? That was one of the crucial features not supported.

I'm not sure why C was created over B. ANSI C had more abstraction than K&R C; early versions of C didn't have function prototypes or type checking. There seems to have been a slow progression towards more abstractions, as the machines used for compiling got bigger. Many of the early bad decisions in C probably come from having to run the compiler in a very small, slow machine. Today we expect to get the whole progra…

The memory model you describe is overly simplistic, and is not actually mandated by the C standard. Too many assumptions in that area will lead to undefined behavior.

Example: conversions between function pointers and regular pointers... https://stackoverflow.com/questions/32437069/c-void-function...

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

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

> I can write C, but for the life of me I don't have the slightest clue how the assembly code will look like.

Compiler Explorer can help a ton. https://gcc.godbolt.org/

I recommend liberal use of Compiler Explorer to verify claims during code review.

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

#209
post #68

I find this article to be disingenuous. Yes, C isnt "how a computer really works". Neither is assembly. The way a computer works is based off of transistors and some concepts built on top of that (ALUs for example). However, there is no need to know about any of that because you're presented with an abstraction (assembly). And thats really what people mean when they say C is closer to how a computer actually works: i…

Except it isn't, not really. Even just the distinction between the stack & heap is wrong. They aren't different things, just different functions called on the otherwise identical memory. It's why things like Go work fine, because the stack isn't special. It's just memory. malloc & free are also totally divorced from how your program interacts with the OS memory allocator, even. GC'd languages don't necessarily sit on…

Stack accesses _are_ different in hardware these days, which is why AArch64 brings the stack pointer into the ISA level vs AArch32, and why on modern x86 using RSP like a normal register devolves into slow microcoded instructions. There's a huge complex stack engine backing them that does in fact give you better access times averaged vs regular fetches to cache as long as you use it like a stack, with stack-like data access patterns. The current stack frame can almost be thought of as L½.

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

#210

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 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 -- operations that do not trivially map to assembly language.

C is close to the machine precisely because it declines to implement any high-level semantics like these.

Post reply on HN