这是我在C中循环重新定义一个数组的后续跟踪.
考虑以下两个例子:
#include <stdio.h>
int main(void)
{
int i = 1;
while (i <= 10) {
int t[10];
if (i == 1)
t[0] = 100;
else {
t[0]++;
printf("i = %d, t[0] = %d\n", i, t[0]);
}
i++;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
结果如预期:
i = 2, t[0] = 101
i = 3, t[0] = 102
i = 4, t[0] = 103
i = 5, t[0] = 104
i = 6, t[0] = 105
i = 7, t[0] = 106
i = 8, t[0] = 107
i = 9, t[0] = 108
i = 10, t[0] = 109
Run Code Online (Sandbox Code Playgroud)
第二个(略有不同)与VLA(在C99中引入):
#include <stdio.h>
int main(void)
{
int i = 1;
while (i <= 10) {
int t[i];
if (i == 1)
t[0] = 100;
else {
t[0]++;
printf("i = %d, t[0] = %d\n", i, t[0]);
}
i++;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我得到的第二个例子(在gcc 4.4.7中)对我来说很奇怪:
i = 2, t[0] = 101
i = 3, t[0] = 102
i = 4, t[0] = 103
i = 5, t[0] = 1
i = 6, t[0] = 2
i = 7, t[0] = 3
i = 8, t[0] = 4
i = 9, t[0] = 1637935601
i = 10, t[0] = 1637935602
Run Code Online (Sandbox Code Playgroud)
对于在循环内声明的VLA,C标准中是否有任何规则/引用或者它只是编译器的错误?
在这两种情况下,您都应该看到垃圾值.您的数组对象(VLA与否)在循环的每次迭代中再次开始其生命周期.每当它开始它的生命周期中,它具有不确定的价值.在你的第一个例子中,你很幸运,那些"不确定"的值恰好与前一次迭代在内存中留下的值相同.同时,VLA的潜在机制是不同的,所以你只是没有得到VLA的幸运.
请注意,在C语言中,VLA和非VLA对象的生命周期的定义不同.非VLA对象{在相应范围的开头处开始它们的生命周期,而VLA对象在声明点开始它们的生命周期.甚至对于没有初始化程序定义的非VLA对象,当控制传递其定义时,它们会立即获取不确定的值.
但是这些细节在这里描述的情况下很重要:在局部变量之前的GOTO.但是,这在您的特定示例中无关紧要,因为在您的示例中,两个数组都会在每次迭代时被销毁并重新创建.