我有一个使用VC++ dot net 3构建的Windows表单应用程序。
有一个整数变量x。
当我以调试模式运行应用程序时,x的值为0;但是当我在没有调试的情况下运行应用程序时,x的值会变得非常大,达到113901996。
该变量已初始化为int x = 0。
为什么会这样?我需要检查哪些设置吗?
我有一个使用VC++ dot net 3构建的Windows表单应用程序。
有一个整数变量x。
当我以调试模式运行应用程序时,x的值为0;但是当我在没有调试的情况下运行应用程序时,x的值会变得非常大,达到113901996。
该变量已初始化为int x = 0。
为什么会这样?我需要检查哪些设置吗?
编辑:根据您提供的新信息,您忘记初始化变量,这种行为是可以预料的。您正在读取垃圾内存。
现在,即使您初始化了变量,只要不以影响程序的可观察行为的方式使用它,仍然可以复制此行为。这就是我最初的答案所处理的内容 - 我会将其留在这里供以后参考。
您实际上是否在使用 x
?如果您只是初始化它,优化器很可能会排除整个过程。
如果它没有影响程序的可观察行为,优化器可以自由地从二进制文件中剪切任何内容。
监视器也可能欺骗您,在发布模式下我见过这种情况。
您能发布一些最小化的代码来复制问题吗?
如果您通过一些输出进行测试,例如:
cout << x;
x
是0
。int main()
{
int x = 0;
x = 3;
return 0;
}
在发布模式下(启用完整优化),将翻译为:
00401000 xor eax,eax
00401002 ret
这个变量不仅没有被赋值,它甚至不存在;与调试版本相反:
00411370 push ebp
00411371 mov ebp,esp
00411373 sub esp,0CCh
00411379 push ebx
0041137A push esi
0041137B push edi
0041137C lea edi,[ebp-0CCh]
00411382 mov ecx,33h
00411387 mov eax,0CCCCCCCCh
0041138C rep stos dword ptr es:[edi]
0041138E mov dword ptr [x],0
00411395 mov dword ptr [x],3
0041139C xor eax,eax
这段代码中创建了一个变量x并且赋值两次(参见 mov dword ptr [x],0
和 mov dword ptr [x],3
)。
如果变量x修改了可观察的输出,即:
int main()
{
int x = 0;
x = 3;
cout << x;
return 0;
}
00401000 mov ecx,dword ptr [__imp_std::cout (40203Ch)]
00401006 push 3
00401008 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char>
0040100E xor eax,eax
可以看出,即使如此,x
实际上并没有生成,而是将值 3
放在堆栈上直接打印。
但在这种情况下观察到的行为是相同的,因为打印的是值 3
。对于用户来说,变量 x
的值应为 3
是否被打印或直接打印 3
都是无关紧要的。
x
。在发布模式下,变量不会被初始化为它们的默认值,即0(如果您没有指定初始值)。
这是一种强制用户初始化所有变量的方法。在C++中,你真的应该这样做。其他语言如C#会为你默认设置为0/其他默认值,但在C++中,由你决定。
我认为你的问题在于初始化。你说你正在分配一个初始值为0
,但当你测量时,你得到了11301996。要么你没有按照你的期望进行初始化(我的最佳猜测),要么你的输出/测试程序存在问题。发帖你的代码,我很乐意提供进一步的帮助。
(编辑:确实,通过初始化你的变量,问题得到了解决。这并不意味着变量被“优化掉”了,显然不是这样——优化器永远不会优化代码以返回大的、随机的值,而期望的是零。)
cout
并得到相同的结果了吗?我在回答中付出了一些努力,希望能得到一些反馈。 - Luchian Grigore