我在reddit上问了一个问题。问题实际上是为什么自动对象(没有 VLA)的生命周期的起点在对象的范围之前?
我得到了答案,这可以作为我的问题的例子。
代码
#include <stdio.h>
int main(void) {
int i = 0;
back:
printf("i = %d", i);
int j;
if (i < 5) {
if (i == 0)
j = 0;
j += i;
printf(", j = %d\n", j);
i++;
goto back;
}
printf("\n");
}
输出
i = 0, j = 0
i = 1, j = 1
i = 2, j = 3
i = 3, j = 6
i = 4, j = 10
i = 5
但是有人说“当它的声明达到时,它的值j
变得不确定,......”因为 C17 6.2.4p6(用我的粗体字)
对于这样一个没有可变长度数组类型的对象,它的生命周期从进入与其关联的块开始,直到该块的执行以任何方式结束。(进入封闭的块或调用函数会暂停,但不会结束当前块的执行。)如果递归地进入块,则每次都会创建对象的新实例。对象的初始值是不确定的。如果为对象指定了初始化,则在执行块时每次到达声明或复合文字时都会执行它;否则,每次达到声明时,该值变得不确定。
仅转到当前块中的标签不同于在递归函数或迭代语句中重复整个关联块。从这个角度来看,我认为j
不受规则的影响(但这只是我的想法)。
顺便说一句,我认为无论我们以哪种方式思考,都存在矛盾。
- 如果int j;
没有在每个序列中重新创建,则为重新定义。
- 如果int j;
在每个序列中重新创建,j
则应具有来自第二个序列的垃圾值。但输出显示为好像保留了“j”的值。
我一遍又一遍地阅读引用的部分文档,但无法理解。我错过了什么?