问题描述
考虑C语言中的一个循环,该循环在循环的主体中声明一个字符数组.在每次迭代中,将修改数组的字符,直到到达结尾为止.最后,将打印变量.该描述将扩展到下一个代码:
Consider a loop in C which declares a character array in the loop's body. At each iteration, a character of array is modified until the end is reached. At the end, the variable is printed. The description would expand to the next code:
#include <stdio.h>
int main(void) {
int i = 0;
for (;;) {/* same as: while(1) { */
char x[5];
x[i] = '0' + i;
if (++i == 4) {
x[i] = '\0'; /* terminate string with null byte */
printf("%s\n", x);
break;
}
}
return 0;
许多人可能希望将 0123
作为输出.但是由于某些原因,在启用优化功能( -O1
及更高版本)的情况下进行编译时,GCC 4.7不会这样做.而是将随机数据放入字符数组的前字节,该字节变为:
Many may expect 0123
as output. But for some reason GCC 4.7 does not do that when compiling with optimization enabled (-O1
and higher). It instead puts random data in the first bytes of the character array, which becomes:
| 0 | 1 | 2 | 3 | 4 |
| RANDOM | '3' | '\0' |
从语言的角度来看,我认为这是逻辑行为:终止块后自动变量就消失了,因此应该期望上述随机"行为.
I think that this is logical behaviour from the language point of view: automatic variables are gone after a block is terminated, so the above "random" behaviour should be expected.
正确的行为应该是什么?我知道将 x
的声明移到循环之外可以修复"它,但这并没有说明此代码段的行为.实际问题是Netfilter中的错误.
What should be the correct behaviour? I know that moving the declaration of x
outside the loop "fixes" it, but that does not say anything about the behaviour of this snippet. The real-world problem is a bug in Netfilter.
推荐答案
由于数组是在循环主体的作用域内声明的,因此您可以将其视为为每次循环迭代在自动存储区域中分配的新数组.除了在当前迭代过程中已分配给索引的字符之外,该单元化数组的内容是未定义的,因此您看到的是不确定的值:
Since the array is declared inside the scope of loop's body, you can think of it as of a new array being allocated in the automatic storage area for each loop iteration. The content of that unititialized array is undefined, except for the character at the index to which you have assigned during the current iteration, so what you see there is indeterminate value:
关闭优化后,阵列将落在自动存储中的同一位置,因此您的程序会很幸运;但是,这绝不能保证.
When optimization is turned off, the array lands in the same spot in the automatic storage, so your program gets lucky; however, this is by no means guaranteed.
将数组移动到循环外部,如下所示:
Move the array to outside the loop, like this:
int i = 0;
char x[5];
for (;;) {
x[i] = '0' + i;
if (++i == 4) {
x[i] = '\0'; /* terminate string with null byte */
printf("%s\n", x);
break;
}
}
这篇关于循环体中声明的变量在迭代过程中是否保留?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!