局部变量未初始化的检测问题

时间:2022-11-27 19:43:33
其实是个vc问题 :)

// vs2008 debug win32 win7/x64
int temp;

int main()
{
int k;

// 下面这行代码不一定如此,反正不管与k有关无关
// 只要动用了lea指令,k似乎就被认为已初始化了,既不报C4700警告
// warning C4700: uninitialized local variable 'k' used
// 也没有运行时中断
// Run-Time Check Failure #3 - The variable 'k' is being used without being initialized
_asm lea eax,temp

int t=k;

return 0;
}


有什么合理解释?

或是bug也不奇怪,反正bug多了去了,只求一个官方承认是bug或公认是bug的链接

15 个解决方案

#1


局部变量未初始化的检测问题
这个明显是没有初始化嘛

#2


不是已经用汇编出事化了吗

#3


局部变量未初始化的检测问题
我还是调试下看看汇编什么情况在进来

#4


引用 2 楼 quwei197874 的回复:
不是已经用汇编出事化了吗


_asm lea eax,temp 这行如果不写,即使release下不会运行时中断,但c4700警告也是报的

这行汇编既没有向k写入,也没有从k读取

#5


汇编下这句没什么用
至于为什么写了这句就不报警告,确实有点诡异~

#6


没有初始化,回报错的

#7


引用 5 楼 qscool1987 的回复:
汇编下这句没什么用
至于为什么写了这句就不报警告,确实有点诡异~


呵呵,搜半天都不得其解

另外有一个问题也不知道vs2010解决了没有
int main()
{
for(int i;i<10;++i);
// 只要有try/catch存在
// for循环里的i未初始化就不报C4700警告了
// 但debug下的运行时中断还是有的

try{}catch(...){}

return 0;
}

#8


引用 6 楼 ximenwuji 的回复:
没有初始化,回报错的


vs哪个版本?

#9


编译器的问题,没法解释
不一定所有编译器会对未初始化的局部变量出warning的
(我手头如GCC,CB就不报,而VC,LCC就会报的)
因为局部变量在栈上,而栈上数据肯定是可读写的,所以未初始化的结果最多读出来个随机数据而已,不会导致程序崩溃的,属于非重要问题.
至于为会么加了lea就不报warning了,只有MS编写编译器的人了解了

#10


引用 7 楼 yisikaipu 的回复:
引用 5 楼 qscool1987 的回复:汇编下这句没什么用
至于为什么写了这句就不报警告,确实有点诡异~

呵呵,搜半天都不得其解

另外有一个问题也不知道vs2010解决了没有

C/C++ code
int main()
{
    for(int i;i<10;++i);
    // 只要有try/catch存在
    // for循环里的i未初始化就不报C4……

甭纠结这些问题了,太不好解释了,对于基本类型除了全局和静态的,其他的变量不手动初始化,编译器都不管,按道理要报警告的,解释嘛......

#11


该回复于2011-12-31 13:43:14被版主删除

#12


该回复于2011-12-31 10:50:02被版主删除

#13


引用 9 楼 keiy 的回复:
因为局部变量在栈上,而栈上数据肯定是可读写的,所以未初始化的结果最多读出来个随机数据而已,不会导致程序崩溃的,属于非重要问题.


C++标准没有要求局部变量一定保存在栈上,而且认为读取未初始化变量属未定义行为。从这个角度看,未初始化警告还是重要的。我越来越有标准洁癖了 :)

int k; // 局部变量
int t=k; // 未定义行为

$3.10/7
Whenever an lvalue appears in a context where an rvalue is expected,  the lvalue is converted to an rvalue;see 4.1, 4.2, and 4.3.

$4.1/1
An lvalue (3.10) of a non-function, non-array type T can be converted to an rvalue. If T is an incomplete type, a program that necessitates this conversion is ill-formed. If the object to which the lvalue refers is not an object of type T and is not an object of a type derived from T, or  if the object is uninitialized, a program that necessitates this conversion has undefined behavior. ...

#14


该回复于2011-12-31 14:10:21被版主删除

#15


这个问题仍然不知道官方/正式的依据,但发现函数体内只要出现 _asm ,其后的语句就不警告了,运行时也不检测

所以,如果需要不改其它代码,不改配置,又希望不产生警告和检测,就加塞一条 _asm nop

这个“方法”,在VS2012上调试旧项目可能有用,因为使用未初始化变量,在VS2012,不再只是警告,而是错误,编译都不行

若想在VS2012上追踪旧项目中bug来龙去脉,只需在函数体开头加塞一条_asm nop,就屏蔽了错误警告和检测

#1


局部变量未初始化的检测问题
这个明显是没有初始化嘛

#2


不是已经用汇编出事化了吗

#3


局部变量未初始化的检测问题
我还是调试下看看汇编什么情况在进来

#4


引用 2 楼 quwei197874 的回复:
不是已经用汇编出事化了吗


_asm lea eax,temp 这行如果不写,即使release下不会运行时中断,但c4700警告也是报的

这行汇编既没有向k写入,也没有从k读取

#5


汇编下这句没什么用
至于为什么写了这句就不报警告,确实有点诡异~

#6


没有初始化,回报错的

#7


引用 5 楼 qscool1987 的回复:
汇编下这句没什么用
至于为什么写了这句就不报警告,确实有点诡异~


呵呵,搜半天都不得其解

另外有一个问题也不知道vs2010解决了没有
int main()
{
for(int i;i<10;++i);
// 只要有try/catch存在
// for循环里的i未初始化就不报C4700警告了
// 但debug下的运行时中断还是有的

try{}catch(...){}

return 0;
}

#8


引用 6 楼 ximenwuji 的回复:
没有初始化,回报错的


vs哪个版本?

#9


编译器的问题,没法解释
不一定所有编译器会对未初始化的局部变量出warning的
(我手头如GCC,CB就不报,而VC,LCC就会报的)
因为局部变量在栈上,而栈上数据肯定是可读写的,所以未初始化的结果最多读出来个随机数据而已,不会导致程序崩溃的,属于非重要问题.
至于为会么加了lea就不报warning了,只有MS编写编译器的人了解了

#10


引用 7 楼 yisikaipu 的回复:
引用 5 楼 qscool1987 的回复:汇编下这句没什么用
至于为什么写了这句就不报警告,确实有点诡异~

呵呵,搜半天都不得其解

另外有一个问题也不知道vs2010解决了没有

C/C++ code
int main()
{
    for(int i;i<10;++i);
    // 只要有try/catch存在
    // for循环里的i未初始化就不报C4……

甭纠结这些问题了,太不好解释了,对于基本类型除了全局和静态的,其他的变量不手动初始化,编译器都不管,按道理要报警告的,解释嘛......

#11


该回复于2011-12-31 13:43:14被版主删除

#12


该回复于2011-12-31 10:50:02被版主删除

#13


引用 9 楼 keiy 的回复:
因为局部变量在栈上,而栈上数据肯定是可读写的,所以未初始化的结果最多读出来个随机数据而已,不会导致程序崩溃的,属于非重要问题.


C++标准没有要求局部变量一定保存在栈上,而且认为读取未初始化变量属未定义行为。从这个角度看,未初始化警告还是重要的。我越来越有标准洁癖了 :)

int k; // 局部变量
int t=k; // 未定义行为

$3.10/7
Whenever an lvalue appears in a context where an rvalue is expected,  the lvalue is converted to an rvalue;see 4.1, 4.2, and 4.3.

$4.1/1
An lvalue (3.10) of a non-function, non-array type T can be converted to an rvalue. If T is an incomplete type, a program that necessitates this conversion is ill-formed. If the object to which the lvalue refers is not an object of type T and is not an object of a type derived from T, or  if the object is uninitialized, a program that necessitates this conversion has undefined behavior. ...

#14


该回复于2011-12-31 14:10:21被版主删除

#15


这个问题仍然不知道官方/正式的依据,但发现函数体内只要出现 _asm ,其后的语句就不警告了,运行时也不检测

所以,如果需要不改其它代码,不改配置,又希望不产生警告和检测,就加塞一条 _asm nop

这个“方法”,在VS2012上调试旧项目可能有用,因为使用未初始化变量,在VS2012,不再只是警告,而是错误,编译都不行

若想在VS2012上追踪旧项目中bug来龙去脉,只需在函数体开头加塞一条_asm nop,就屏蔽了错误警告和检测