如何解决程序有效性;循环内定义的变量的生存期和范围
考虑程序
#include <stdio.h>
int main(void) {
for (int curr = 0; curr < 3; curr++) {
int prev;
if (curr) {
printf("%d\n",prev); //valid; prev has 0 or 1
}
prev = curr;
}
}
有效吗?prev
的生存期和范围是什么?
-
在
prev
循环中将有3个不同的for
,它们的生存期和范围。
不同的prev
可以(但不是必须)共享相同的地址。
程序无效。 -
prev
循环中将有3个for
,它们的生存期和范围。prev
将共享相同的地址,就像使用static
定义的一样。
程序有效。 -
将有1个
prev
,就像它是在for
循环之外定义的一样。
程序有效。
注意:问题是在this answer
上的讨论中提出的解决方法
在使用C89或仅在更高版本的C中使用提供的循环结构时,代码不可能在对象的生存期内到达自动对象声明上方的位置。但是,C99增加了使用goto
将控制权从声明之下的点转移到声明的对象生存期内的之上的能力。我不确定任何非人为设计的程序在多大程度上依赖以下事实:使用goto
将控制权转移到非VLA对象的声明之上并不会终止其生命周期,但是该标准要求实现允许对于这种行为,例如
void test(void)
{
int pass=0;
int temp;
int *p;
int result;
firstPass:
if (pass)
{
temp = *p;
goto secondPass;
}
pass++;
int q=1;
p=&q;
q++;
goto firstPass;
secondPass:
return temp + q;
}
q
的生命周期将在代码进入test
时开始,并且即使代码分支到声明上方的某个点,也会扩展到函数执行的整个过程。如果执行到达带有初始化程序的声明,则此时将分配对象的值;否则,将为对象赋值。如果它到达了没有初始化程序的声明,则该对象的值在那时将变得不确定,但是如果代码跳过该声明,该对象将保留其值。
ISO/IEC 9899:TC3 对此非常清楚:
在原帖中,prev
在循环中有一个常量地址,但它的值在求值时是不确定的。因此,代码表现出未定义的行为。
我认为这使得原帖 (1-4) 中的所有答案都不正确。
,1
prev
被视为在循环实例内部具有作用域的自动变量
这意味着在每次迭代时都会释放所有自动变量,然后 再次执行循环时重新获取。
实际上,for-loop
的定义是for语句每次执行一次(在这种情况下,增加变量)并测试条件,
因此,即使查看代码,您也可以看到方括号内的范围已完成
每次循环结束。
分配局部变量的地址(或保存该值的寄存器)的任何保证均无效。它完全依赖于实现。
,三个不同且截然不同的prev
不需要(不需要)共享地址或值。
在每个循环中,将“创建”和“删除”一个不同的prev
。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。