cstack-frame

Stack frame and value pointer


I am unsure as to why i is set to 1234 during the second run of f()? I thought that when the first f() was executed to completion the stack frame for the first f() will be "popped", which I thought would meant that i is now an unpredictable value. The same goes for the third f() function call after calling g(5432). Why is the i suddenly set to 5432 instead?

 void f();
 void g(int);
 
 void main() {
     f();
     f();
     g(5432);
     f();
 }
 
 void f() {
     int i;
     printf("%d\n", i);
     i = 1234;
 }
 
 void g(int val) {
     printf("%d\n", val);
 }

This is the output I get when running the code:

0
1234
5432
5432

Solution

  • This is undefined behavior in action.

    Because you're reading an uninitialized variable in f, there's no guarantee of the program's behavior when you do so. In fact, if you compile with optimization enabled, you'll likely see different behavior.

    That being said, here's what's probably happening.

    While it's true that the stack frame of a function is "popped" after the function returns, calling another function will typically end up using the same stack space that was used for the prior function call. There aren't any instructions emitted that zero out the values used in the prior stack frame, so you end up seeing the values that happened to be there before.

    In the case of multiple calls to f, the local variable i ends up being on the same place of the stack in each call. In the case of g there's no local variable but the passed parameter ends up in the same position of the stack as i in f.

    But again, there's no guarantee of this behavior. If I compile your code without optimizations I get the same output as you, but if I compile with -O1 I get the following output:

    0
    0
    5432
    0