Why C use stacks for storing the local variables? Is this just to have independent memory space or to have feature of automatic clearing of all the local variables and objects once it goes out of scope?

I have few more questions around the same,

Question 1) How local variables are referenced from the instruction part. Consider NewThreadFunc is the function which is called by createThread function.

DWORD WINAPI NewThreadFunc(PVOID p_pParam)
{
int l_iLocalVar1 = 10;
int l_iLocalVar2 = 20;

int l_iSumLocalVar = l_iLocalVar1 + l_iLocalVar2;
}

The stack for this thread would look like this,

| p_pParam       |
| NewThreadFunc()|
| 10             |
| 20             |
| 30             |
|                |
.
.
.

Now my question is, while executing this function how would CPU know the address of local variables (l_iSumLocalVar, l_iLocalVar1 and l_iLocalVar2)? These variables are not the pointers that they store the address from where they have to fetch the value. My question is wrt the stack above.

Question 2) If this function further calls any other function how would the stack behave to it? As I know, the stack would get divided into itself further. If this is true how the local variables of the callee function gets hidden from the called function. Basically how the local variables maintains the scope rules?

I know these could be very basic questions but some how I could not think an answer to these.

有帮助吗?

解决方案

Firstly, it is not "Windows" that uses stack for local variables. It has absolutely nothing to do with "Windows", or with any other OS for that matter. It is your compiler that does that. Nobody forces your compiler to use system stack for that purpose, but normally this is the simplest and most efficient way to implement local variables.

Secondly, compilers use stacks to store local variables (be that system-provided stacks or compiler-implemented stack) simply because stack-like storage matches the language-mandated semantics of local variables very precisely. The storage duration of local variables is defined by their declarative regions (blocks) which strictly nest into each other. This immediately means that storage durations of local variables follow the LIFO principle: last in - first out. So, using a stack - a LIFO data structure - for allocating objects with LIFO storage duration is the first and the most natural thing that comes to mind.

Local variables are typically addressed by their offset from the beginning of the currently active stack frame. The compiler knows the exact offset of each local variable at compile time. The compiler generates the code that will allocate the stack frame for the current function by: 1) memorizing the current position of the stack pointer when the function is entered (let's say it is memorized in register R1) and 2) moving the current stack pointer by the amount necessary to store all local variables of the function. Once the stack frame is allocated in this fashion, your local variables l_iLocalVar1, l_iLocalVar2 and l_iSumLocalVar will simply be accessed through addresses R1 + 6, R1 + 10 and R1 + 14 (I used arbitrary offsets). In other words, local variables are not accessed by specific address values, since these addresses are not known at compile time. Instead local variables are accessed through calculated addresses. They are calculated as some run-time base address value + some compile-time offset value.

其他提示

  1. Normally the system calling convention reserves a register to be used as a "stack pointer". Local variable accesses are made relative to this register's value. Since every function must know how much stack space it uses, the compiler emits code to ensure the stack pointer is adjusted correctly for each function's requirements.

  2. The scope of local variables is only enforced by the compiler, since it's a language construct, not anything to do with hardware. You can pass addresses of stack variables to other functions and they'll work correctly.

why is the stack used for local variables?

Well, the stack is an easy to use structure to reserve space for temporary variables. It has the benefit that it will be removed almost automatically when the function returns. An alternative would be to allocate memory from the OS, but then this would cause heavy memory fragmentation. The stack can be easily allocated as well as freed again, so it is a natural choice.

All the variable addresses are relative to the stack pointer that is incremented at each function call or return. Fast easy way to allocate and cleanup memory used by these variables.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top