Is it possible to automatically allocate a memory stack inside a function?

I apologize if this was asked before, but I did not find anything ...

For the "normal" x86 architecture:

When I call a large function in C ++, is the allocated memory immediately for all the variables of the stack? Or there are compilers that can (and do) resize the stack, even if the function is not finished.

For example, if a new area starts:

int largeFunction(){ int a = 1; int b = 2; // .... long code .... { // new scope int c = 5; // .... code again .... } // ..... 

}

Can the call stack โ€œgrowโ€ also for the variable c at the beginning of a separate area and โ€œshrinkโ€ at the end? Or do current compilers always produce code that affects the stack pointer on the input and return value of a function? Thanks for your reply in advance.

+6
source share
3 answers

1) How long a function has nothing to do with memory allocation, regardless of stack or heap.

2) When the stack is โ€œdistributedโ€, it depends only on the compilation method to make the most efficient code. Effective has a wide range of requirements. All compilers have options for changing optimizer goals for speed and size, and most compilers can also optimize for lower stack consumption and other parameters.

3) Automatic variables can go onto the stack, but this is not necessary. A lot of variables should be "allocated" to your processor registers. This greatly speeds up the code and saves the stack. But it depends a lot on the processor platform.

4) When the compiler creates a new frame stack, it is also a matter of code optimization. Compilers can perform "idle execution" if it saves resources or is better suited to the architecture. Therefore, the question of when the stack stack is used cannot be given. A new area (open bracket) may be the point to place the new stack frame, but this is never a guarantee. It is sometimes inefficient to recalculate all relative stack addresses of all called functions from the actual volume.

5) Some compilers can also use heap memory for automatic variables. This is often seen on embedded cores if access using special instructions is faster than relative stack addressing.

But usually this is not very important when the compiler does what it wants. The only thing you need to remember sometimes is that you must ensure that your stack is large enough. Often, system calls for new threads have options for setting the size of the stack. Thus, you should know how many stack sizes your implementation requires. But in all other cases: Forget to think. This work was done perfectly from the developers of your compiler.

+7
source

I donโ€™t know the answer (and I hope you only want to know, because you are curious, since no valid program can tell), but you can check the behavior of your compiler by calling like before the new area, and again after the new area:

 std::intptr_t stackaddr() { int i; return reinterpret_cast<std::intptr_t>(&i); } 

If you get the same result, it means the stack was already configured before c .

In g ++ 4.7, a change was made that allows the compiler to reuse the stack space c after completing its area where previously any new variables after this point increased stack usage: "g ++ now correctly reuses the stack space allocated for temporary objects when their time runs out life, which can significantly reduce stack consumption for some C ++ functions. " But I think that this only affects how much stack is reserved when entering the function, and not when / where it is reserved.

+2
source

This completely depends on the runtime conventions of the system used, however, the processor architecture usually plays a big role in the decision, since the architecture determines which stack control can be safely used. On older PowerPCs under MacOS X, for example, the stack frames were always fixed size, one atomic storage of the stack pointer at the lower end of the new stack frame would allocate it, dereferencing the stack pointer was equivalent to the appearance of the entire stack frame.

Current systems, such as Linux, and (correct me if I am wrong). Windows on x86 has a more dynamic approach with atomic taps and pop instructions (there is no atomic pop music in PowerPC), where function call parameters are pushed onto the stack before each function call, effectively resizing the selected stack frame each time.

So, yes, in many modern systems, the compiler can change the size of the stack frame, but in other systems, such an operation is at least difficult to perform (although not necessary).

0
source

Source: https://habr.com/ru/post/955689/


All Articles