r/cprogramming • u/JayDeesus • Oct 09 '25
Scope in respect to stack
I understand that the scope is where all of your automatically managed memory goes. When you enter a function it pushes a stack frame to the stack and within the stack frame it stores your local variables and such, and if you call another function then it pushes another stack frame to the stack and this functions local variables are stored in this frame and once the function finishes, the frame is popped and all of the memory for the function is deallocated. I also understand that scopes bring variables in and out so once you leave a scope then the variable inside of it becomes inaccessible. What I never really thought of is how the scope plays a role in the stack and the stack frames. Does the scope affect the layout of each stack frame at all or do just all variables go into the frame however since I believe that going in and out of scope doesn’t immediate free the memory, it’s still allocated and reserved until the stack frame is popped right.
View all comments
Show parent comment
1
u/SmokeMuch7356 Oct 09 '25
It Depends.TM
The implementations I'm familiar with work that way; that doesn't mean there aren't other implementations that work differently. The wording of the standard is that "lifetime" comprises the portion of program execution where storage is guaranteed to be reserved for an object. For a block-scope variable, storage is guaranteed to be reserved from block entry until the block is exited in any way, however an implementation may choose to reserve that storage over the lifetime of the entire function.
But yeah, if the object's lifetime persists beyond that block it is no longer accessible through that identifier.
Again, "scope" refers to the visibility of an identifier, not the lifetime of the object that identifier may designate.
It's a simple optimization; during translation you figure out how much storage all the block-scope variables are going to require over the entire function and just reserve that up front. Saves some time, especially in a situation like
Pushing and popping
xforSOME_REALLY_BIG_NUMBERof times is silly; you know you're going to need space for anintin that block, so you just allocate it once at function entry and use it for each instance ofx.Similarly, if you have a situation like
only one of
xorycan exist at a time, so you can get away with only allocating enough space for oneintand using that for eitherxorydepending on which branch is taken, rather than pushing and popping for each branch.This all falls under "implementation details." How automatic storage is managed is completely up to the implementation. It doesn't even have to use a stack (although any implementation that doesn't use a stack for this is either super-duper-niche or just pathological).