是的,这是未定义的访问行为any已经达到它的变量生命尽头。这里的范围和存储持续时间略有不同。范围更多的是“变量标识符何时可见?”存储时间是“变量本身什么时候存在?”。
你可以让事情在范围内并且持久,例如:
int main (void) {
int spoon = 42;
// spoon is both in scope and enduring here
return 0;
}
或者超出范围但持久:
int main (void) {
int *pSpoon;
{
static int spoon = 42;
pSpoon = &spoon;
}
// spoon is out of scope but enduring here (use *pSpoon to get to it)
return 0;
}
您还可以使用超出范围且不持久的变量,例如:
int main (void) {
// spoon is neither in scope nor enduring here ("there is no spoon")
return 0;
}
事实上,唯一不能拥有的就是变量在作用域内但不持久。标识符与存储绑定在一起,因为允许没有后备存储的变量没有什么意义。
我不是在这里讨论指针,这是一个额外的间接级别 - 范围内指针变量always具有指针值本身的存储空间,即使它指向的东西to其存储期限已结束或尚未开始。
事实上,未定义的行为在某些情况下可能起作用,但这绝不会使行为得到定义,事实上,这是未定义行为最烦人的特征之一,因为它有时does工作。不然更容易被发现。
在这种特殊情况下,b
变量存储持续时间结束于内部右大括号,因此尝试在那之后访问它是不明智的。
该标准的控制部分是c11 6.2.4 Storage duration of objects
(稍微解释一下以删除不必要的部分):
对象具有决定其生命周期的存储持续时间。有四个存储
持续时间:静态、线程、自动和分配。
其标识符声明时没有链接且没有存储类说明符 static 的对象具有自动存储持续时间。
对于这样的对象,其生命周期从进入与其关联的块开始延伸,直到该块的执行以任何方式结束。