在哪个区段?BSS, .DATA,其他)的可执行文件的静态变量存储,以便他们没有名称冲突? 例如:


foo.c:                         bar.c:
static int foo = 1;            static int foo = 10;
void fooTest() {               void barTest() {
  static int bar = 2;            static int bar = 20;
  foo++;                         foo++;
  bar++;                         bar++;
  printf("%d,%d", foo, bar);     printf("%d, %d", foo, bar);
}                              }

如果我编译这两个文件并将其链接到重复调用fooTest()和barTest的主程序,printf语句将独立递增。这是有意义的,因为foo和bar变量是翻译单元的局部变量。

但是存储分配在哪里呢?

需要明确的是,假设您有一个工具链,该工具链将以ELF格式输出文件。因此,我认为在可执行文件中必须为那些静态变量保留一些空间。 为了便于讨论,让我们假设我们使用GCC工具链。


当前回答

数据的存储位置取决于实现。

然而,静态的含义是“内部联动”。因此,该符号是编译单元(foo.c, bar.c)内部的,不能在编译单元外部引用。因此,不能有名称冲突。

其他回答

当程序加载到内存中时,它被组织成不同的段。其中一个段是DATA段。数据段进一步细分为两部分:

初始化数据段:所有全局、静态和常量数据都存储在这里。 未初始化数据段(BSS):所有未初始化的数据都存储在这个段中。

下面是一个图表来解释这个概念:

这里有一个很好的链接解释这些概念:C中的内存管理:堆和堆栈

如前所述,存储在数据段或代码段中的静态变量。 您可以确保它不会被分配到堆栈或堆上。 没有碰撞风险,因为static关键字定义变量的范围为文件或函数,如果发生碰撞,有编译器/链接器警告你。

数据的存储位置取决于实现。

然而,静态的含义是“内部联动”。因此,该符号是编译单元(foo.c, bar.c)内部的,不能在编译单元外部引用。因此,不能有名称冲突。

在编译单元中声明的数据将进入该文件输出的. bss或.Data。BSS中初始化的数据,data中未初始化的数据。

静态数据和全局数据之间的区别在于文件中包含的符号信息。编译器倾向于包含符号信息,但只标记全局信息。

链接器尊重这些信息。静态变量的符号信息要么被丢弃,要么被破坏,这样静态变量仍然可以以某种方式引用(使用调试或符号选项)。在这两种情况下,编译单元都不会因为链接器首先解析本地引用而受到影响。

这是如何(容易理解):