【问题标题】:Difference between C global and local _static_ variables?C全局变量和局部_static_变量之间的区别?
【发布时间】:2022-06-16 17:25:37
【问题描述】:

我的 C 生锈了,请帮帮我。

static int i = 42;
int main()
{
}

创建一个具有全局范围和内部链接的变量i。这意味着任何人都可以引用它,但只有翻译单元(.c 文件)中的条目不会破坏链接器。在程序链接时分配,在输入main()之前初始化。

void foo()
{
    static int i = 69;
}

创建一个具有函数作用域但没有链接的变量。这意味着foo() 之外的任何内容都无法引用它,即使编译器没有大声喊叫,获取这个(本质上受保护的全局)变量的地址也是 UB。它在程序链接期间分配,并在首次调用foo() 时初始化。

请指正!

【问题讨论】:

    标签: static linkage c17


    【解决方案1】:

    创建一个具有全局范围和内部链接的变量 i。这意味着任何人都可以引用它,但只有翻译单元(.c 文件)中的条目不会破坏链接器。它在程序链接期间分配,并在进入 main() 之前进行初始化。

    正确,除了正式术语是文件范围(在任何函数之外),不要与“全局”混为一谈,“全局”通常意味着可以在任何地方访问。在这种情况下,变量是在文件范围内声明的,但它不是“全局”可访问的。通常,非正式术语“全局”与正式术语外部链接extern关键字的用法一起使用。

    创建一个具有函数作用域但没有链接的变量。

    不,它创建一个具有块范围的变量。存在一个正式的术语function scope,但它指的是goto 标签的范围。 C 有四个作用域:文件作用域函数作用域块作用域函数原型作用域。那些不是语言律师或意大利面条程序员的人只需要了解文件范围和块范围。

    意味着 foo() 之外的任何东西都不能引用它

    正确。

    即使编译器没有喊出来,取这个(本质上受保护的全局)变量的地址也是UB

    不,这是错误的。范围不能确定变量是否可以访问,存储持续时间可以。您的两个示例都声明了具有相同 静态存储持续时间 但范围不同的变量。具有静态存储持续时间的变量在整个程序执行期间持续存在并保持有效。

    因此,返回指向具有静态存储持续时间的块范围变量的指针是很好且定义明确的。 (但它可能不是线程安全的,但这是另一回事。)

    在程序链接时分配

    正确。

    并在第一次调用 foo() 时初始化。

    不,这是错误的。所有具有静态存储持续时间的变量,无论其范围如何,都会在调用 main() 之前进行初始化。在您的示例中使用显式初始化程序(通常意味着它在名为 .data 的段中分配)或为零以防它未显式初始化(​​所有设置为零的静态存储变量通常在名为 @ 的段中分配987654324@).

    【讨论】:

      猜你喜欢
      • 2015-10-21
      • 1970-01-01
      • 1970-01-01
      • 2013-01-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-17
      • 2018-12-22
      相关资源
      最近更新 更多