Are C stack variables stored in reverse order?

I am trying to understand how C allocates memory on the stack. I always thought that variables on the stack can be represented as member variables of structs, they occupy a sequential, contiguous block of bytes on the stack. To help illustrate this problem, I found somewhere, I created this small program that reproduced this phenomenon.

#include <stdio.h> #include <stdlib.h> #include <string.h> void function(int *i) { int *_prev_int = (int *) ((long unsigned int) i - sizeof(int)) ; printf("%d\n", *_prev_int ); } void main(void) { int x = 152; int y = 234; function(&y); } 

See what I do? Suppose sizeof(int) is 4: I am looking for 4 bytes behind the passed pointer, as this will read 4 bytes to where int y on the caller's stack.

It did not print 152. It is strange when I look at the following 4 bytes:

 int *_prev_int = (int *) ((long unsigned int) i + sizeof(int)) ; 

and now it works, prints everything in x inside the caller's stack. Why does x have a lower address than y ? Are stack variables overloaded?

+6
source share
2 answers

The stack organization is completely unspecified and implementation specific. In practice, this depends on a large number of compiler (even its version) and optimization flags.

Some variables do not even sit on the stack (for example, because they are simply stored inside some registers or because the compiler optimized them, for example, by inserting, constant bending, etc.).

By the way, you may have a hypothetical implementation of C that does not use any stack (even if I cannot name such an implementation).

To learn more about stacks:

Unfortunately, I do not know a low level language (for example, C, D, Rust, C ++, Go, ...), where the call stack is available at the language level. This is why coding the garbage collector for C is difficult (since the GC needs to scan call stack pointers) ... But see Bem's conservative GC for a very practical and pragmatic solution.

+10
source

Currently, almost all processor architectures support stack instructions (for example, LDM, STM instructions in ARM). Compilers using a stack of these tools. In most cases, when data is pushed onto the stack, the stack pointer decreases (grows down) and increases when data is pushed from the stack.

So the processor architecture and the compiler depend on the stack.

+3
source

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


All Articles