静态变量存储

时间:2011-01-21 04:58:53

标签: c

在C中,存储在内存中的静态变量在哪里?假设有两个静态变量,一个是函数局部变量,另一个是全局变量。如何在符号表中保留此条目?请解释一下。

3 个答案:

答案 0 :(得分:13)

C 中,可以将它们存储在实现认为合适的任何位置。 C标准没有规定实现是如何做的,只是它如何行为。

通常,所有静态存储持续时间变量(函数内的静态函数和函数外的所有变量)都将存储在同一区域中,无论它们是在文件级还是在函数内。

上面括号中的那一点很重要。在函数之外,static不会像在函数中那样决定变量的存储持续时间。它决定变量是否在当前翻译单元之外可见。 函数外的所有变量都是静态存储持续时间。

并且,关于符号表,这是仅在构建过程中存在的构造。一旦生成了可执行文件,就没有符号(当然排除了调试信息,但这与代码的执行无关)。此时对变量的所有引用几乎肯定都是硬编码的地址或偏移量。

换句话说,编译器会使用名称来确定您所指的变量。


您可以在此处查看有关如何存储变量的示例。考虑以下小C程序:

#include <stdio.h>
int var1;
static int var2;
int main (void) {
    int var3;
    static int var4;

    var1 = 111;
    var2 = 222;
    var3 = 333;
    var4 = 444;

    return 0;
}

这将生成以下程序集:

.file             "qq.c"
.comm             var1,4,4
.local            var2
.comm             var2,4,4
.text
.globl            main
.type             main, @function
main:
    pushl         %ebp
    movl          %esp, %ebp
    subl          $16, %esp
    movl          $111, var1
    movl          $222, var2
    movl          $333, -4(%ebp)
    movl          $444, var4.1705
    movl          $0, %eax
    leave
    ret
.size             main, .-main
.local            var4.1705
.comm             var4.1705,4,4
.ident            "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"
.section          .note.GNU-stack,"",@progbits

您可以看到var1var2var4(静态存储持续时间)都有.comm行,以将其标记为常用条目,受制于链接器整合。

此外,var2var3var4(在当前传输单元之外不可见的)都有.local行,因此链接器获胜不要用它们来满足其他目标文件中未解析的外部。

并且,通过在链接文件时检查ld --verbose的输出,您可以看到所有常见条目最终都在.bss区域中:

  .bss            :
  {
   *(.dynbss)
   *(.bss .bss.* .gnu.linkonce.b.*)
   *(COMMON)
   : : :
  }

答案 1 :(得分:1)

不可能推广到每个编译器,但这是最常用的方式。

链接器将为变量添加一块内存,这些变量在加载时初始化但在运行时可修改。所有静态变量都将放在此块中,无论它们是本地还是全局。

答案 2 :(得分:0)

鉴于以下来源:

static int a_static_var = 5;

void foo(void)
{
    static int a_static_var = 6;

    return;
}

Visual Studio按如下方式编译变量(至少在这个实例中 - 详细信息因编译器而异,取决于选项):

_DATA   SEGMENT
_a_static_var DD 05H
?a_static_var@?1??foo@@9@9 DD 06H           ; `foo'::`2'::a_static_var
_DATA   ENDS

因此,两个静态变量最终都出现在数据段中 - 作用于函数的静态函数的名称被破坏,以至于它不会与不同函数或源文件中的类似变量“匹配”。 / p>

编译器实现可以随意处理这种情况,但总体思路通常是类似的。