Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Strange stack behavior in C

Tags:

c

stack

I'm worried that I am misunderstanding something about stack behavior in C.

Suppose that I have the following code:

int main (int argc, const char * argv[]) 
{
    int a = 20, b = 25;
    {
        int temp1;
        printf("&temp1 is %ld\n" , &temp1);
    }

    {
        int temp2;
        printf("&temp2 is %ld\n" , &temp2);
    }
    return 0;
}

Why am I not getting the same address in both printouts? I am getting that temp2 is one int away from temp1, as if temp1 was never recycled.

My expectation is for the stack to contain 20, and 25. Then have temp1 on top, then have it removed, then have temp2 on top, then have it removed.

I am using gcc on Mac OS X.

Note that I am using the -O0 flag for compiling without optimizations.

Tho those wondering about the background for this question: I am preparing teaching materials on C, and I am trying to show the students that they should not only avoid returning pointers to automatic variables from functions, but also to avoid taking the address of variables from nested blocks and dereferencing them outside. I was trying to demonstrate how this causes problems, and couldn't get the screenshot.

like image 621
Uri Avatar asked Mar 21 '09 23:03

Uri


2 Answers

The compiler is completely within its rights not to optimize temp1 and temp2 into the same location. It has been many years since compilers generated code for one stack operation at a time; these days the whole stack frame is laid out at one go. (A few years back a colleague and I figured out a particularly clever way to do this.) Naive stack layout probably puts each variable in its own slot, even when, as in your example, their lifetimes don't overlap.

If you're curious, you might get different results with gcc -O1 or gcc -O2.

like image 90
Norman Ramsey Avatar answered Nov 11 '22 03:11

Norman Ramsey


There is no guarantee what address stack objects will receive regardless of the order they are declared.

The compiler can happily reorder the creation and duration of stack variables providing it does not affect the results of the function.

like image 4
Andrew Grant Avatar answered Nov 11 '22 02:11

Andrew Grant