是否可以在单个C文件中声明具有相同名称的多个静态变量?

时间:2010-05-28 12:33:20

标签: c static

是否可以在具有不同范围的单个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不支持名称修改)?

6 个答案:

答案 0 :(得分:18)

功能 - 本地静态变量 全局静态变量 不同。
由于可以有多个具有相同名称的函数本地静态(假设它们都在不同的范围内),编译器可能必须在内部更改它们的名称(包含函数的名称或行号或其他),所以链接器可以区分它们。

答案 1 :(得分:6)

可见性范围之间存在差异;此外,static关键字具有基于范围的不同含义。

static关键字添加到sVar的块范围版本(myPrint :: sVar和main :: sVar)会更改其范围(生命周期),但不会更改能见度;两者仅在其各自的函数中可见,并将在其本地范围内隐藏或隐藏文件范围版本。它表示变量具有静态范围,这意味着它们的存储器在程序启动时分配并保持到程序终止(与自动或局部范围相反,其寿命限于它们的定义范围)。

static关键字添加到sVar的文件范围版本不会更改其范围(文件范围变量根据定义具有静态范围),但它确实会更改其对其他翻译的可见性单位;该名称未导出到链接器,因此无法通过其他翻译单元的名称访问该名称。它仍然在当前翻译单元中可见,这就是myPrint2可以访问它的原因。

答案 2 :(得分:2)

您的第一个sVar是全局归档,第二个是函数myPrint()的本地,第三个是本地main()

在函数外部无法访问函数级静态变量 - 它们只是在后续调用中保留其值。我假设您在运行代码时已经注意到了这一点。

答案 3 :(得分:2)

阻止范围界定。阅读K&amp; R上。

答案 4 :(得分:1)

静态关键字在全局和本地时具有不同的含义,第一个sVar只是其他翻译单元无法使用的全局变量。 sVarmyPrint()中的静态变量main()位于不同的范围内,因此它们是不同的变量。在myPrint() sVar的正文中指的是本地静态(隐藏全局sVar),在myPrint2()中它指的是全局(它不被任何本地隐藏),以及在main()中,它引用了本地static sVar,它从声明它的那一刻起再次隐藏了全局。

答案 5 :(得分:0)

这两个函数都会创建不同的堆栈,因此静态部分也会不同 因此有可能。