正在访问超出范围的静态未定义行为

Is accessing a static out of scope undefined behavior?

本文关键字:静态 未定义 范围 访问      更新时间:2023-10-16

在与我的一位同事交谈时,他们说:

foo() {
    int *p;
    {
        int x = 5;
        p = &x;
    }
    int y = *p;
}

创建未定义的行为,因为生存期规则和范围规则会 未指定。

然而:

foo() {
    int *p;
    {
        static int x = 5;
        p = &x;
    }
    int y = *p;
}

不是未定义的!您最终会遇到"间接范围界定"问题。

术语的使用听起来不正确。
我知道静态与范围无关。
第二种情况是否已经定义了行为?

是的,第二种情况具有明确定义的行为。 static变量基本上是一个全局变量,其名称的作用域为声明它的作用域。 它在第一次进入作用域时初始化,然后在程序的生命周期内继续存在。

因此,当我们到达

int y = *p;

p指向您无法再访问(无法返回到该代码)但仍具有有效生存期的变量。

引用标准 [basic.stc.static]

所有没有动态存储持续时间、没有线程存储持续时间和不是局部的变量都具有静态存储持续时间。这些实体的存储应在计划期间持续

强调我的

第一种情况未定义,因为本地作用域的生存期x}结束,在其生存期结束后尝试引用它是未定义的行为。

引用自这里

静态存储类指示编译器在程序的生命周期内保持局部变量的存在,而不是在每次进入和超出范围时创建和销毁它。因此,将局部变量设为静态允许它们在函数调用之间维护其值。

所以是的,在第二种情况下x在程序的整个生命周期内存在。

因此定义了行为。