这个问题在这里已有答案:
请考虑以下C ++代码段:
#include <iostream>
int main() {
int x;
std::cout << x << '\n';
return 0;
}
正如预期的那样,打印的结果将是不可预测的,因为变量x
尚未初始化。如果你运行它可能第二次得到458785234和348934610。但是,如果您通过以下方式更改代码:
#include <iostream>
int main() {
int x;
std::cout << x << std::endl;
return 0;
}
现在,x打印总是等于零。这是为什么?请注意,引入的唯一变化是std::endl
。任何人都可以解释为什么这将q赋予x
变量?
正如预期的那样,印刷的结果将是不可预测的......
现在,x打印总是等于零。这是为什么?
之所以如此,是因为行为未定义。
您希望这个数字“不可预测”。似乎你没有预测数字为零。这应该符合您的期望。
你没有做任何使数字非零,所以你为什么期望这个数字不为零?
另一方面,您可能一直期望行为不会改变,因为程序的更改似乎是无关的。这种期望是不明智的。如果更改程序的任何部分,则不保证未定义的行为是相同的未定义行为。实际上,即使您不进行任何更改,也不能保证行为相同。另一方面,行为也不能保证不同。没有关于程序行为的任何信息。这就是未定义行为的含义。
使用Ubuntu 16.04上的gcc 5.4.0,我在两个版本的代码中都获得了0
。但这并不重要,因为x
未初始化并试图阅读它是未定义的行为。任何事情都可能发生,具体取决于所使用的特定编译器和系统,不保证任何特定行为。
现在考虑以下内容:
#include <iostream>
void foo() {
int x;
std::cout << x << std::endl;
}
void bar() {
int y = 123;
std::cout << y << std::endl;
}
int main() {
foo();
bar();
foo();
return 0;
}
在我的机器上打印:
0
123
123
所以我的猜测是我的编译器在程序启动之前没有对堆栈区域进行零初始化,但是后来为了避免不必要的工作而没有这么做。
但正如我之前所指出的,这些行为是未定义的。标准对此没有要求,因此我们不能假设任何具体的事情总是发生。
它是未定义的行为你得到的是编译器调用使用Microsoft Visual C ++它甚至不编译(错误C4700:未初始化的局部变量'x'使用)