eta*_*iso 3 c variables initialization undefined-behavior
我有点困惑.据我所知,如果你在C中声明一个int,而不是初始化它,例如:int x;
所以它的价值是不确定的.因此,如果我们尝试使用它或应该有未定义的行为.
所以,如果我在VS2010中运行以下代码,它会导致程序崩溃.
int main(){
int a;
printf("%d\n",a);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
现在让我们来看看下一个代码,它没有提供任何警告而且没有崩溃(为什么?)
void foo(int *var_handle){
// do nothing
}
int main(){
int a;
foo(&a);
printf("%d\n",a); // works, prints some big value
return 0;
}
Run Code Online (Sandbox Code Playgroud)
你能解释一下这种行为吗?我们只添加了对一个什么都不做的函数的调用,但现在程序不会崩溃.
小智 8
读取未初始化变量的值会导致未定义的行为.未定义的行为意味着它可能崩溃.这并不意味着它会或它有义务崩溃.
未初始化的变量具有未指定的值 - 它只是未知它的值是什么.所以在实践中,任何理智的实现,这种代码可能永远不会崩溃.有一个有效的内存地址支持变量,它有一些垃圾内容,printf()读取没有问题,将其解释为整数并打印它,就是这样.
使用未初始化的值不会直接导致未定义的行为。
根据 C 2011(n1570 草案)6.7.9 10,具有自动存储持续时间的未初始化对象具有不确定的值。根据 3.19.2 1,不确定值是未指定的值或陷阱表示。类似的文字出现在 C 1999 中。
如果对象具有陷阱表示,则可能会发生未定义的行为。但是,如果该对象具有未指定的值,则程序必须在该对象具有某个确定的值时表现出来;只是没有指定该对象具有哪个值。不允许程序仅仅因为未指定值而崩溃。
令人惊讶的是,您报告在 Visual Studio 2010 中显示的简单程序崩溃,因为我不希望该int类型在 Visual Studio 2010 中具有任何陷阱表示。可能是某些源文件与您预期的不同,被编译并崩溃了,或者您已在 Visual Studio 2010 中启用特殊调试功能,尝试跟踪未初始化的对象(但在使用 的第二种情况下失败foo)。
我建议您从头开始重复测试,将本问题中显示的代码粘贴到新文件中,并使用默认选项编译该新文件。
当然,Visual Studio 2010不符合C标准,甚至不符合旧的1999年标准,因此它不必遵守上述条款。实际上,关于 Visual Studio 2010 的所有内容都是 C 标准的未定义行为。