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

时间:2016-06-13 17:52:33

标签: c++ scope static undefined-behavior lifetime

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

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

创建未定义的行为,因为生命周期规则和范围规则可以   没有说明。

     

但是:

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

未定义!你最终会遇到“间接范围”问题。

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

2 个答案:

答案 0 :(得分:31)

是的,第二种情况有明确定义的行为。 static变量基本上是一个全局变量,其名称的范围限定在它声明的范围内。它在第一次输入范围时初始化,然后在程序的生命周期内保持不变。

所以当我们到达

int y = *p;

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

引用标准[basic.stc.static]

  

所有没有动态存储持续时间,没有线程存储持续时间且不是本地的变量都具有静态存储持续时间。 这些实体的存储应在程序期间持续

强调我的

第一种情况是未定义的,因为本地范围x的生命周期在}结束,并且在其生命周期结束后尝试引用它是未定义的行为。

答案 1 :(得分:1)

引用来自 here

  

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

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

因此定义了行为。