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, fragmentation is a risk, the resource is 'unlimited', and the lifetime is unscoped.
Your statement is equivalent to saying "there's no difference between pointers and integers" - technically, they are both just numbers that live in registers or somewhere in memory. In reality, that approach will not get you far in computer science.
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.)
You are more than welcome to use a stack in an assembly language too. What you say certainly can be true, but many architectures include dedicated stack pointer registers and operations to manipulate them, either special-purpose (AVR, __SP_H__ and __SP_L__, push, pop) or more generic (x86 %sp, push, pop). I'd argue that functions exist at the hardware level to some extent too in architectures that support, for instance, link registers (PPC $LR) and special instructions (call, ret instead of a generic jump family). Calling conventions, sure, are an attraction over functions.
> Your statement is equivalent to saying "there's no difference between pointers and integers" - technically, they are both just numbers that live in registers or somewhere in memory. In reality, that approach will not get you far in computer science.
No, because in reality those are handled by different computational units. Integers are handled by the ALU, and pointers are handled by the loader. They are distinct things to the CPU.
Stack & heap have no such distinction. There isn't even a heap in the first place. There's as many heaps of as many sizes as you want, as the "heap" concept is an abstraction over memory (strictly speaking over virtual address space - another concept C won't teach you, yet is very important for things like mmap). It's not a tangible thing to the computer.
Same with the stack. It's why green-threads work, because the stack is simply an abstraction over memory.
> No, because in reality those are handled by different computational units. Integers are handled by the ALU, and pointers are handled by the loader. They are distinct things to the CPU.
I strongly disagree. Yes some execution units are more let's say "dedicated" to pointers than other, and obviously ultimately you will dereference your pointers, so you will load/store, but compilers happily emit lea to do e.g. Ax9+B and in the other direction, add or sub on pointers. Some ISA even have almost no pointer "oriented" register (and even x64 has very few)
Exactly, this will vary wildly between architectures. I would accept the statement on, for instance, a Harvard architecture but the world is a lot more nuanced in the much more common von Neumann architecture.
No no, haha, that's also not quite right. You can save the stack frame to memory then load it back which is what green threads do [1]. This includes the register state also, which is not what we're talking about here when we say "stack" -- we're referring to stack variables, not full frames. Full frames are even further from the heap, by virtue of including register states which must be restored also.
Although, it sounds like you're agreeing with me that there is in fact a difference between the stack and the heap because to your point one exists supported at the hardware level with instructions and registers, and one doesn't exist or can exist many times over. Hence, different.
> 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.
I'd argue that given special purpose registers exist on most platforms to support a stack, and instructions dedicated to manipulating them (x86 %sp, push, pop) that the stack is in fact a hardware concept. The heap, however, is left as an exercise to the reader.
> I'd argue that given special purpose registers exist on most platforms to support a stack, and instructions dedicated to manipulating them (x86 %sp, push, pop) that the stack is in fact a hardware concept.
True enough; however sometimes access to "the heap" (in C terms) will use those instructions, and sometimes access to "the stack" will not. Learning one or two assembly languages is well worth doing, since they offer a coherent abstraction that is genuinely relevant to the implementation of higher-level languages. Not so C.
Well, you can just write a naive allocator that just bumps pointer and never deallocates things :). To appreciate stack vs heap, you have to learn a bit about memory management and some basic algorithms like dlmalloc, imho.
You're joking. There's a very serious distinction between the stack and the heap - perhaps they live in the same memory but they are used very differently and if you mix them up your things will break.
There is no hardware distinction between stack memory and heap memory.
In fact C teaches a model of a semi-standard virtual architecture - loosely based on the DEC PDP7 and/or PDP11 - which is long gone from real hardware.
Real hardware today has multiple abstraction layers under the assembly code, and all but the top layer is inaccessible.
So there's no single definitive model of "How computers work."
They work at whatever level of abstraction you need them to work. You should definitely be familiar with a good selection of levels - and unless you're doing chip design, they're all equally real.
I'm not sure it really pretends that there is so much a distinction so much as C supports stack allocation/management as a language feature, but heap support is provided by libraries.
And C pretends there's a distinction between the stack & heap that doesn't actually exist. There is no significant difference there.