Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are C stack variables stored in reverse?

I'm trying to understand how C allocates memory on stack. I always thought variables on stack could be depicted like structs member variables, they occupy successive, contiguous bytes block within the Stack. To help illustrate this issue I found somewhere, I created this small program which reproduced the 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'm doing? Suppose sizeof(int) is 4: I'm looking 4 bytes behind the passed pointer, as that would read the 4 bytes before where int y in the caller's stack.

It did not print the 152. Strangely when I look at the next 4 bytes:

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

and now it works, prints whatever in x inside the caller's stack. Why x has a lower address than y? Are stack variables stored upside down?

like image 654
doc_id Avatar asked Feb 17 '15 09:02

doc_id


People also ask

Where are stack variables stored?

Stack storage space for local variables and parameters exists only when the function is active (within the stack frame for the function's activation on the stack.) Global variables are stored in the data section.

How are variables stored in stack?

The stack is used for dynamic memory allocation, and local variables are stored at the top of the stack in a stack frame. A frame pointer is used to refer to local variables in the stack frame.

How is C storing variables in memory?

In C, global variables are stored with the program code. I.e. the space to hold them is part of the object file (either in the data or bss section), instead of being allocated during execution (to either the stack or heap).

Which type of variables are stored on stack memory?

Whenever an object is created, it's always stored in the Heap space and stack memory contains the reference to it. Stack memory only contains local primitive variables and reference variables to objects in heap space.


1 Answers

Stack organization is completely unspecified and is implementation specific. In practice, it depends a lot of the compiler (even of its version) and of optimization flags.

Some variables don't even sit on the stack (e.g. because they are just kept inside some registers, or because the compiler optimized them -e.g. by inlining, constant folding, etc..).

BTW, you could have some hypothetical C implementation which does not use any stack (even if I cannot name such implementation).

To understand more about stacks:

  • Read the wikipage on call stacks, tail calls, threads, and on continuations

  • Become familiar with your computer's architecture & instruction set (e.g. x86) & ABI, then ...

  • ask your compiler to show the assembler code and/or some intermediate compiler representations. If using GCC, compile some simple code with gcc -S -fverbose-asm (to get assembler code foo.s when compiling foo.c) and try several optimization levels (at least -O0, -O1, -O2 ....). Try also the -fdump-tree-all option (it dumps hundred of files showing some internal representations of the compiler for your source code). Notice that GCC also provides return address builtins

  • Read Appel's old paper on garbage collection can be faster than stack allocation, and understand garbage collection techniques (since they often need to inspect and possibly change some pointers inside call stack frames). To know more about GC, read the GC handbook.

Sadly, I know no low-level language (like C, D, Rust, C++, Go, ...) where the call stack is accessible at the language level. This is why coding a garbage collector for C is difficult (since GC-s need to scan the call stack pointers)... But see Boehm's conservative GC for a very practical and pragmatic solution.

like image 154
Basile Starynkevitch Avatar answered Oct 11 '22 20:10

Basile Starynkevitch