例如,请考虑以下事项:
int main(void) {
int K;
int Y;
printf("%d", K==Y);
return 0;
}
输出是否有可能成为1
?
读取未初始化变量值的结果是未定义的,这意味着任何事情都可能发生。我会说输出可能是 1。
这里的问题是变量K
和Y
都有自动存储持续时间,并且永远不会获取其地址 - 它可以用register
存储类声明,C11 6.3.2.1p2 说
如果 lvalue 指定了一个自动存储持续时间的对象,该对象本可以使用寄存器存储类声明(从未获取其地址(,并且该对象未初始化(未使用初始值设定项声明,并且在使用之前未对其执行任何赋值(,则行为未定义。
因为行为是未定义的,所以任何事情都可能发生。在实践中,之所以存在此规则,是因为在某些计算机体系结构中,处理器寄存器将在进入函数时设置为"unset" - 访问此类寄存器实际上会触发硬件陷阱,从而导致程序崩溃。
然后,此规则导致其他编译器对这些进行各种疯狂的操作 - 可能是在分配给变量之前不会为变量分配寄存器,因此您可能会看到变量的值在执行时发生变化,因此可能是连续调用
printf("%d", K==Y);
printf("%d", K==Y);
可能会打印不同的值。
使用自动存储读取未初始化的局部变量具有未定义的行为。 任何事情都可能发生:
- 输出可以
1
- 输出可以
0
- 输出可以
Hello world
- 可能没有任何输出
- 计算机可能会回到9个月左右,这将是尝试纠正一些历史事故或至少将其货币化的便捷方法。唉,不太可能发生。