为什么此代码中的`bar`没有静态存储持续时间?

时间:2016-02-08 15:58:05

标签: c static scope declaration

代码优先:

#include <stdio.h>

void foo()
{
        static int bar;
}

int main()
{
        bar++;
        return 0;
}

编译器(Clang)抱怨:

static.c:10:2: error: use of undeclared identifier 'bar'

static int bar;中的foo()语句不应该给bar静态存储持续时间,这会使它在main函数之前被声明和初始化吗?

2 个答案:

答案 0 :(得分:5)

您将变量的范围存储持续时间混淆。

C11标准中所述,章节§6.2.1,标识符范围

  • 用于文件范围
  

[...]如果声明标识符的声明符或类型说明符   出现在任何块或参数列表之外,标识符具有文件范围,即   终止于翻译单元的末尾。 [...]

功能(或阻止)范围

  

[...]如果是声明符或类型说明符   声明标识符出现在块内或参数声明列表中   一个函数定义,标识符有块作用域,它终止于   相关块。 [...]

在您的情况下,bar的文件范围为foo()。因此main()

OTOH,存储持续时间部分,

  

在没有存储类说明符的情况下声明其标识符的对象   _Thread_local,可以是外部或内部链接,也可以是存储类   说明符static,具有静态存储持续时间。它的一生就是整个执行   在程序启动之前,程序及其存储的值只初始化一次。

因此,总而言之,bar具有静态存储持续时间,但范围仅限于foo()函数。所以,它是

  

main()函数

之前声明并初始化

(在main()开始之前,确切地说)但在main()中不可见且无法访问。

答案 1 :(得分:2)

在函数中将某些内容标记为static会将其存储重新定位到堆栈之外,并允许其值在多个调用中保持不变。

然而,标记某些内容static不会改变变量的范围。虽然您当然可以创建一个针对bar并从main处理它的指针,但编译器会因为范围界定而将bar视为未定义main