访问静态超出范围的未定义行为吗?
Posted
技术标签:
【中文标题】访问静态超出范围的未定义行为吗?【英文标题】:Is accessing a static out of scope undefined behavior? 【发布时间】:2016-10-14 06:02:26 【问题描述】:在与我的一位同事交谈时,他们说:
foo() int *p; int x = 5; p = &x; int y = *p;
创建未定义的行为,因为生命周期规则和范围规则确实如此 不指定。
但是:
foo() int *p; static int x = 5; p = &x; int y = *p;
不是未定义的!您最终会遇到“间接范围界定”问题。
术语的使用听起来不正确。 我知道静态与范围无关。 第二种情况是否已经定义了行为?
【问题讨论】:
评论不用于扩展讨论;这个对话是moved to chat。 【参考方案1】:是的,第二种情况具有明确定义的行为。 static
变量基本上是一个全局变量,其名称的范围仅限于声明它的范围。它在第一次进入范围时被初始化,然后在程序的整个生命周期中都存在。
所以当我们到达时
int y = *p;
p
指向一个您无法再访问(无法返回该代码)但仍具有有效生命周期的变量。
引用标准[basic.stc.static]
所有没有动态存储时长、没有线程存储时长、非本地变量都有静态存储时长。 这些实体的存储将持续到程序的持续时间
强调我的
第一种情况是未定义的,因为本地范围 x
的生命周期在 处结束,并且在其生命周期结束后尝试引用它是未定义的行为。
【讨论】:
第二种情况是*p = 42;
未定义吗?
@sunqingyao:没关系,为什么不呢? C 不要求存储位置具有名称。否则,malloc
将毫无用处。【参考方案2】:
引用自 here
静态存储类指示编译器在程序的生命周期内保持局部变量的存在,而不是在每次进入和离开范围时都创建和销毁它。因此,将局部变量设为静态允许它们在函数调用之间保持其值。
所以是的,在第二种情况下,x
在程序的整个生命周期内都存在。
因此定义了行为。
【讨论】:
你在引用什么? 静态存储和static
storage-class specifier是有区别的。
@Olaf 能否提供一些关于静态存储和存储类说明符之间差异的链接,以便我更好地理解它?
标准对此很清楚。这不是我的答案。在 C++ 中可能会有所不同;我评论的印象是这个问题是关于 C 的——你仍然应该验证自己,我对 C++ 标准不太熟悉。如果手头有权威资源,请不要引用二级/三级资源。
我觉得,这是用比权威资源更简单的语言解释的。无论如何,我会在以后的帖子中关注它。以上是关于访问静态超出范围的未定义行为吗?的主要内容,如果未能解决你的问题,请参考以下文章