C 静态变量存储

C 静态变量存储,c,C,在C语言中,静态变量存储在内存中的什么位置?假设有两个静态变量,一个是函数的局部变量,另一个是全局变量。如何在符号表中维护此条目?请解释。不可能推广到每个编译器,但这是最常用的方法 链接器将为在加载时初始化但在运行时可修改的变量留出一块内存。所有静态变量都将放置在此块中,无论它们是本地变量还是全局变量。在C中,它们可以存储在实现认为合适的任何位置。C标准并不规定实现如何做事情,只规定它的行为 通常,所有静态存储持续时间变量(函数内的静态变量和函数外的所有变量)将存储在同一区域中,而不管它们是在文

在C语言中,静态变量存储在内存中的什么位置?假设有两个静态变量,一个是函数的局部变量,另一个是全局变量。如何在符号表中维护此条目?请解释。

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

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

在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;
}
您可以看到,
var1
var2
var4
(静态存储持续时间)都有一个
.comm
行,将它们标记为公共条目,由链接器合并

此外,
var2
var3
var4
(在当前传输单元之外不可见的那些)都有一个
.local
行,因此链接器不会使用它们来满足其他对象文件中未解析的外部

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

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

鉴于以下来源:

static int a_static_var = 5;

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

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

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


编译器实现可以以任何方式自由处理此问题,但总体思路通常是类似的。

您所说的“静态变量”是什么意思?静态存储持续时间?或内部链接?@prp,
gcc-S
将汇编代码输出到标准输出。
static int a_static_var = 5;

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

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