是否可以在单个C文件中声明具有相同名称的多个静态变量?
是否可以在具有不同范围的单个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); }
现在我的问题是,因为所有“静态”变量将驻留在同一部分(.data)中,那么我们如何在一个部分中拥有多个具有相同名称的变量?
我使用objdump
检查不同的部分,发现所有静态变量( sVar
)都在.data部分,但名称不同:
0804960c l O .data 00000004 sVar 08049610 l O .data 00000004 sVar.1785 08049614 l O .data 00000004 sVar.1792
为什么编译器正在更改变量的名称(因为C不支持名称修改)?
函数本地静态变量与全局静态变量不同 。
由于可以有任意数量的函数本地静态函数(如果它们都在不同的范围内),编译器可能必须在内部更改它们的名称(包含函数的名称或行号或其他),所以链接器可以区分它们。
能见度和范围之间存在差异; 另外, static
关键字具有基于范围的不同含义。
将static
关键字添加到sVar
的块范围版本(myPrint :: sVar和main :: sVar)会改变它们的范围 (生命周期),但不会改变它们的可见性; 两者仅在其各自的函数中可见,并将在其本地范围内隐藏或隐藏文件范围版本。 它表示变量具有静态范围,这意味着它们的存储器在程序启动时分配并保持到程序终止(与自动或局部范围相反,其寿命限于它们的定义范围)。
将static
关键字添加到sVar
的文件范围版本不会改变其范围(文件范围变量根据定义具有静态范围),但它确实改变了其对其他翻译单元的可见性; 该名称未导出到链接器,因此无法通过其他翻译单元的名称访问该名称。 它仍然在当前翻译单元中可见,这就是myPrint2可以访问它的原因。
你的第一个sVar
是全局文件,第二个是函数myPrint()
本地,第三个是main()
本地
函数级静态变量在函数外部不可访问 – 它们只是在后续调用中保留它们的值。 我假设您在运行代码时已经注意到了这一点。
阻止范围。 阅读K&R
static关键字在全局和本地时具有不同的含义,第一个sVar
只是其他转换单元不可用的全局变量。 而myPrint()
和main()
中的静态变量sVar
在不同的范围内,因此它们是不同的变量。 在myPrint()
的主体中, sVar
指的是本地静态(隐藏全局sVar
),在myPrint2()
它指的是全局(它不被任何本地隐藏),而在main()
它指的是本地static sVar
,自宣布之日起再次隐藏全球。
这两个函数都会创建不同的堆栈,因此静态部分也会不同。因此它是可能的。