The semantics of automatic storage necessarily imply #1, but they do not require #2. Indeed, there are widely used implementations which implement #1 using linked lists (e.g. IBM mainframes, and GCC's split stacks or clang's segmented stacks).
Similarly, function recursion semantics necessarily imply #1 for restoring execution flow, but not #2. In addition to the examples above, so-called shadow stacks are on the horizon which maintain two separate stacks, one for function return addresses and another for data.[1] In the near future a single contiguous stack may be atypical.
[1] Some variations might mix data and return addresses if the compiler can prove safe object access. Or the shadow stack may simply contain checksums or other auxiliary information that can be optionally used, preserving ABI compatibility.
[1] https://arcanesentiment.blogspot.com/2014/12/customary-seman...
Oddly you seem to recognize this, so I’m not sure what your point is.
's funny, I am certainly aware of having, at some point, at least skimmed over the C99 standard encountered the concept of a storage duration. But, aside from that brief few hours, virtually the entirety of my C-knowing career has been spent thinking and talking in terms of stacks and heaps.
Meanwhile, in my .NET career, I really did (and, I guess, still do) feel like it was important to keep track of how .NET's distinction is between reference types and value types, and whether or not they were stack or heap allocated was an implementation detail.
I'm not even sure the C memory model depends on the code/stack/heap separation.
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.)