具有子范围的函数的堆栈帧结构

时间:2012-10-13 13:30:16

标签: c scope stackframe storage-class-specifier

以下是代码,我作为参考来理解函数中存在的子范围(或)虚拟范围(仅{})如何影响堆栈帧的结构。

#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;
}

示例输出

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

基于以上行为,我推测以下内容。

  • 范围{}没有创建堆栈框架。
  • 通过这种方式,auto中声明/定义的main变量和子范围{}内的变量共享相同的堆栈帧。
  • 因此main中声明/定义的变量可以在函数内的任何地方自由访问(即使在子范围内)。
  • 在另一方面中的变量声明/在子范围中定义的失去其范围出block.But的其寿命时间是只要堆栈帧存在有效的。

问题:如果上述各点是正确的,那么,为什么不赋予同一变量的多个定义,中的一个发生故障时的代码main,并在{{1的其他}}

2 个答案:

答案 0 :(得分:2)

硬件堆栈在这里无​​关紧要。它只能在函数入口处对所有局部变量增长一次,并且在函数出口处只缩小一次,或者每当定义新的局部变量时它就会增长和缩小,并且当它的封闭{}时,它会被破坏。

相关的是&#34;可见性&#34;变量。

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

在内部/子范围中定义具有与外部/超范围相同名称的对象是完全合法的。后者将在{}范围内被遮盖。

仅供参考,还有一些其他地方可以进行变量定义,例如:在for(;;)语句的第一个表达式中:for (int i = 0; i < 10; i++) ...。该变量i只会在for体内显示,您也可以通过定义另一个i来隐藏它。

答案 1 :(得分:1)

本地变量隐藏外部变量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.*/
    } 
}

在C语言中完全合法(请注意,这在C ++中是非法的!)

在你的例子中,肯定是为内部main_scope创建了一个堆栈框架,但是一旦程序离开内部范围,它就会被释放。