【问题标题】:Why doesn't `bar` in this code have static storage duration?为什么此代码中的 `bar` 没有静态存储持续时间?
【发布时间】:2016-05-18 08:44:28
【问题描述】:

代码先行:

#include <stdio.h>

void foo()
{
        static int bar;
}

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

编译器(Clang)抱怨:

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

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

【问题讨论】:

  • 可以,但不在main的范围内。
  • 存储持续时间与范围/可见性有什么关系?
  • 一旦问题中的问题得到回答,请不要添加其他问题。我正在回滚添加。如果您不同意,请告诉我们。

标签: c static scope declaration


【解决方案1】:

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

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

  • 对于文件范围

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

对于function(或block)作用域

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

在您的情况下,bar 的文件范围在 foo()。所以这在main() 中是不可见的。

OTOH,对于存储时间部分,

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

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

main()函数之前声明和初始化

(准确地说是在main() 开始之前)但在main() 中不可见和可访问。

【讨论】:

    【解决方案2】:

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

    然而,标记 static 并不会改变变量的范围。虽然您当然可以创建一个指向 bar 的指针并从 main 对其进行操作,但由于作用域,编译器会将 bar 视为未定义在 main 中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-02
      • 1970-01-01
      • 2016-07-05
      • 2019-08-09
      相关资源
      最近更新 更多