是否可以在具有不同范围的单个C文件中声明多个具有相同名称的静态变量?我写了一个简单的程序来检查这个,并在gcc中编译并运行良好.
码:
static int sVar = 44;
void myPrint2()
{
printf("sVar = %d\n", sVar++);
}
void myPrint()
{
static int sVar =88;
printf("sVar = %d\n", sVar++);
}
int main(void)
{
static int sVar = 55;
int i = 0;
for (i = 0; i < 5; i++)
myPrint();
printf("sVar = %d\n", sVar);
myPrint2();
return(0);
}
Run Code Online (Sandbox Code Playgroud)
现在我的问题是,因为所有"静态"变量将驻留在同一部分(.data)中,那么我们如何在一个部分中拥有多个具有相同名称的变量?
我曾经objdump检查过不同的部分,发现所有静态变量(sVar)都在.data部分,但名称不同:
0804960c l O .data 00000004 sVar
08049610 l O .data 00000004 sVar.1785
08049614 l O .data 00000004 sVar.1792
Run Code Online (Sandbox Code Playgroud)
为什么编译器正在更改变量的名称(因为C不支持名称修改)?
sbi*_*sbi 20
一个函数局部静态变量的东西比一个不同的全局静态变量.
由于可以有多个具有相同名称的函数本地静态(假设它们都在不同的范围内),编译器可能必须在内部更改它们的名称(包含函数的名称或行号或其他),所以链接器可以区分它们.
能见度和范围之间存在差异; 此外,static关键字具有基于范围的不同含义.
将static关键字添加到sVar(myPrint :: sVar和main :: sVar)的块范围版本会改变它们的范围(生命周期),但不会改变它们的可见性; 两者仅在其各自的函数中可见,并将在其本地范围内隐藏或隐藏文件范围版本.它表示变量具有静态范围,这意味着它们的存储器在程序启动时分配并保持到程序终止(与自动或局部范围相反,其寿命限于它们的定义范围).
将static关键字添加到文件范围版本sVar不会改变其范围(文件范围变量按定义具有静态范围),但它确实改变了其对其他翻译单元的可见性; 该名称未导出到链接器,因此无法通过其他翻译单元的名称访问该名称.它仍然在当前翻译单元中可见,这就是myPrint2可以访问它的原因.