为什么我的变量在调试模式下初始化,但不在发布模式下?

时间:2011-12-21 09:35:58

标签: .net visual-c++

我有一个使用VC ++ dot net 3构建的Windows窗体应用程序。 有一个整数变量,比如int x。

当我在调试模式下运行应用程序时,x = 0的值; 但是当我在没有调试的情况下运行应用程序时,值很大,是113901996。

变量初始化为int x = 0

为什么会这样?我需要检查一些设置吗?

2 个答案:

答案 0 :(得分:3)

编辑:根据您的新信息,您忘记初始化变量,行为是预期的。你在读垃圾记忆。

现在,即使您初始化了变量,您仍然可以通过不以影响程序的可观察行为的方式使用它来复制此行为。这是我原来的答案 - 我将留在这里供将来参考。

你实际上在使用x吗?如果你只是初始化它,优化器很可能会排除整个事情。

如果它不影响程序的可观察行为,优化器可以自由地从二进制文件中删除任何内容。

手表也可能对你说谎,我看到发生在发布模式中。

你能发布一些可以重现问题的最小代码吗?

如果您使用某些输出进行测试,例如:

cout << x;

我确信你会看到x0

编辑:

只是为了解决问题:

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],0mov dword ptr [x],3)。

如果变量修改了可观察输出,即:

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

答案 1 :(得分:-1)

仅仅因为变量未初始化为默认值,即0(如果未指定初始值),则在发布模式下。

这是强制用户初始化所有变量的一种方法。在C ++中,你真的应该这样做。其他语言如C#将默认为0 /其他一些默认值,但在C ++中,它取决于你。

我相信您在初始化时遇到问题。你说你正在指定一个初始值0,但是当你测量到你得到11301996时。要么你没有按照你的预期进行初始化(我的最佳猜测),要么你的输出/测试程序有问题。发布您的代码,我将很乐意为您提供进一步的帮助。

(编辑:是的确,通过初始化你的变量,问题得到了解决。这并不意味着变量被“优化掉”,显然不是 - 优化者永远不会优化代码来返回大的随机值,其中零是预期。)