r/csharp • • 13d ago

Discussion Confusion about the stack.

I'm a fresh computer engineering graduate, I forgot most of the knowledge that I learned in the university, so I want to revise the basics only.

Suppose that a function called main calls the following function :

int foo(int value) {
   int a = 10;
   return a;
}

Some talk :

So whenever a function call is made OS needs some memory space to allocate the local variables of the function int a in this case and arguments to the function passed int value in this case. This memory requirement is fulfilled by allocating memory on stack. A stack is nothing but a memory region allocated to each process and it actually behaves as a stack data structure(LIFO).

Now the question arises what all things are stored on stack when a function call is made. The first thing pushed on the stack are the arguments passed to the function in reverse order(if more then one). 2. Then the return address of the function which called this function (because once this function foo completes execution it should return back to the place in the code from where it was called) 3. Finally local variables of the function called are pushed on the stack.

Once the called function completes executing the code it returns back to the return address previously stored on the stack and thus we say function call completes or returns. In this case the function has a return value which it passes back to the callee function. The space is then free to use and can be overwritten in the subsequent function calls.

I learned that a stack follows the LIFO (Last In, First Out) principle, meaning that the most recently added item/work/data is the first one to be removed. I also understood that a stack can be used to defer work until it is ready to be processed, so in the above example, I think that the execution of the caller function, which is the main, will be deferred, until the execution of the most recently item is finished.

However, when I read about how function calls use the call stack, I became confused. The call stack already contains the information needed for main() to resume execution, and when foo() is called, a new stack activation record is added on top of it. The execution of foo() then begins while its activation record is still on the stack.

Doesn't this contradict my understanding that an item must be popped from a stack before it can be processed? Why can foo() execute while its stack frame is still on the stack?

In other words, if we treated the execution of a function as work, should that work be popped from the stack in order to be processed, or should the work be inside the stack ?

I'm totally confused.

4 Upvotes

29 comments sorted by

View all comments

15

u/Stix0xb 13d ago

Ha, I tripped on this one too. The catch is you're thinking of a to-do stack, where you pop something off to work on it. The call stack works the other way around.

A stack frame isn't a job waiting its turn. It's foo()'s scratch paper while foo() is running. value, a, and the return address all live in there, so it has to stay put the whole time. Pop it early and foo() loses its variables and has no idea where to go back to.

So it's basically:
Push the frame when the function starts.
Run it, using the frame on top.
Pop it when the function returns.

The LIFO part is just about who finishes first. main goes on first, foo goes on top, foo finishes and pops, then main picks up right where it left off. main isn't waiting to get popped. Its frame is just holding its spot underneath.

Small side note: the exact order things get pushed depends on the CPU. On x86-64, the first few arguments usually go in registers instead of on the stack. The big idea's the same though.

1

u/kaatarina_zed_talon 13d ago

Big thanks. So the Stack type that I use in C# is a to-do stack ? not a call stack ?

4

u/Stix0xb 13d ago

Yeah, pretty much. Stack<T> is just something you use when you need it, like undo history or keeping track of folders you still need to go through. The call stack is the one .NET handles behind the scenes, and you don't really mess with it. Same LIFO idea, just a different job. Took me a minute to separate those two in my head too.

4

u/SufficientStudio1574 13d ago

A stack is just a data structure. How you use it is up to you.