Stack frame structure for a function with a sub scope

959 Views Asked by At

Following is the code, that I took as reference to understand how a sub scope (or) dummy scope (just {}) present within the function, impacts the structure of the stack frame.

#include <stdio.h>
int main()
{
   int main_scope=0; /*Scope and life time of the variable is throughout main*/

   {
     //From below two statements I assume that there
     //is no seperate "stack frame" created for just
     //braces {}.So we are free access (scope exists) and
     //modify (lifetime exists) the variable "main_scope"
     //anywhere within main

     main_scope++;
     printf("main_scope++:(%d)\n",main_scope);

    //I expected this statement to throw an error saying
    //"Multiple definition for "main_scope".But it isn't????

    int main_scope=2;
    printf("Value of redefined main_scope:(%d)\n",main_scope);

  }

  printf("Finally main_scope in %s:(%d)\n",__FUNCTION__,main_scope);
  return 0;
}

Sample output

main_scope++:(1)
Value of redefined main_scope:(2)
Finally main_scope in main:(1)

Based on the above behavior, I presume the following.

  • There is no stack frame creation for the scope {}.
  • By this way the auto variables, declared/defined in main and those within the sub scope {} share the same stack frame.
  • So the variables declared/defined in main are free to be accessed anywhere within the function (even within the sub scope).
  • On the other hand the variables declared/defined in the sub scope loses its scope out of the block.But its life time is valid as long as stack frame is present.

Question: If the above points are right, then why isn't the code failing when giving multiple definitions of the same variable, one within main and the other within {}.

2

There are 2 best solutions below

2
On

The hardware stack is irrelevant here. It can grow only once for all local variables at function entry and shrink only once at function exit or it can grow and shrink every time a new local variable is defined and destroyed when the enclosing {} for it is left.

What's relevant is the "visibility" of variables.

int main_scope=0;

{
    main_scope++;
    printf("main_scope++:(%d)\n",main_scope);
    // the main_scope variable that was assigned 0 is the most recent
    // visible declaration of main_scope.

    int main_scope=2;
    // now, the previous declaration of main_scope is obscured by the new one,
    // and so, you're going to access the new one
    printf("Value of redefined main_scope:(%d)\n",main_scope);
}

printf("Finally main_scope in %s:(%d)\n",__FUNCTION__,main_scope);
// the previous scope inside {} is left, so, main_scope is going to be
// the one, to which we assigned 0

It is perfectly legal to define an object in an inner/sub-scope with the same name as in an outer/super-scope. The latter will be obscured for the duration of the {} scope.

Just for the reference, there are some other places, where variable definitions can occur, e.g. inside the first expression of the for(;;) statement: for (int i = 0; i < 10; i++) .... That variable i will only be visible inside the for's body, and you can hide it there as well by defining another i.

0
On

Local variable hides the outer variable main_scope.

int main()
{
    int i=1;
    {

      int i=2;
      printf("%d", i);
      /* Whenever you use i here, it's always the local one that's used. 
      The outer i is hidden by the local i. But the local i will be deallocated 
      once the scope exits.*/
    } 
}

is perfectly legal in C. (Note that this is illegal in C++!)

In your example, certainly a stack frame is created for inner main_scope, but it'll be deallocated once program goes out that inner scope.