在C中循环重新声明VLA数组

Grz*_*ski 2 c c99

这是我在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标准中是否有任何规则/引用或者它只是编译器的错误

AnT*_*AnT 5

在这两种情况下,您都应该看到垃圾值.您的数组对象(VLA与否)在循环的每次迭代中再次开始其生命周期.每当它开始它的生命周期中,它具有不确定的价值.在你的第一个例子中,你很幸运,那些"不确定"的值恰好与前一次迭代在内存中留下的值相同.同时,VLA的潜在机制是不同的,所以你只是没有得到VLA的幸运.

请注意,在C语言中,VLA和非VLA对象的生命周期的定义不同.非VLA对象{在相应范围的开头处开始它们的生命周期,而VLA对象在声明点开始它们的生命周期.甚至对于没有初始化程序定义的非VLA对象,当控制传递其定义时,它们会立即获取不确定的值.

但是这些细节在这里描述的情况下很重要:在局部变量之前的GOTO.但是,这在您的特定示例中无关紧要,因为在您的示例中,两个数组都会在每次迭代时被销毁并重新创建.