请考虑以下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
。谁能解释为什么将0分配给x
变量?
答案 0 :(得分:3)
按预期打印的结果将不可预测...
现在,打印的x始终等于零。为什么会这样?
之所以这样,是因为行为是不确定的。
您希望该数字“无法预测”。似乎您没有预测数字为零。这应该符合您的期望。
您没有做任何使该数字为非零的操作,那么为什么还要期望该数字为非零?
另一方面,您可能一直希望行为不会改变,因为对程序的更改似乎无关紧要。这种期望是不明智的。如果更改程序的任何部分,则未保证未定义行为与未定义行为相同。实际上,即使您不进行任何更改,也不能保证行为相同。另一方面,也不保证行为是不同的。不能保证程序的行为。这就是未定义行为的含义。
答案 1 :(得分:2)
在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
所以我的猜测是我的编译器在程序启动之前对堆栈区域进行了零初始化,但以后再也不用这样做以避免不必要的工作了。
但是正如我之前指出的,这些行为是不确定的。标准对此没有任何要求,因此,我们绝不能假定总是发生任何特定的事情。
答案 2 :(得分:-1)
未定义的行为是编译器调用 使用Microsfot Visual C ++甚至无法编译(错误C4700:使用了未初始化的局部变量'x')