Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/289.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# (如何)调试会改变程序的工作流程?_C#_Visual Studio 2010_Debugging - Fatal编程技术网

C# (如何)调试会改变程序的工作流程?

C# (如何)调试会改变程序的工作流程?,c#,visual-studio-2010,debugging,C#,Visual Studio 2010,Debugging,考虑以下简单程序: var dblMax = Double.MaxValue; var result = (dblMax * 1000) / 1800; Console.WriteLine(result); 当我在调试模式下构建它并运行(Ctrl+F5)或调试(F5)它时,它会打印9.987140856842E+307 当我切换到释放模式并运行(Ctrl+F5)时,它会无限打印8 我理解这种差异是由于在发布模式下进行了一些编译器优化 但是,如果我在发布模式下调试(F5)相同的构建,它会再次打

考虑以下简单程序:

var dblMax = Double.MaxValue;

var result = (dblMax * 1000) / 1800;
Console.WriteLine(result);
当我在调试模式下构建它并运行(Ctrl+F5)或调试(F5)它时,它会打印
9.987140856842E+307

当我切换到释放模式并运行(Ctrl+F5)时,它会无限打印
8

我理解这种差异是由于在发布模式下进行了一些编译器优化

但是,如果我在发布模式下调试(F5)相同的构建,它会再次打印
9.987140856842E+307

我正在调试的事实如何改变计算结果

编辑:


我不会问为什么调试模式和发布模式会产生不同的结果。我想知道为什么发布模式会产生不同的结果,这取决于我是否调试(F5)(Ctrl+F5)。

这与浮点精度密切相关。在调试模式下,编译器使用80位精度。在发布模式下,编译器使用64位截断结果

何时发生这种情况取决于几个配置、设置和环境变量。例如,您可以在发布模式下关闭配置的优化。这应该会有帮助


看看Jon Skeet的回答:

调试时抖动的行为不同

首先,在许多情况下,局部变量的生命周期会发生变化,以便于检查。考虑在计算过程中使用变量后命中断点。如果JITter知道变量不会在表达式之后使用,并且它没有延长变量的生命周期,那么最终可能无法查看该变量,这是调试的核心功能

JITer非常清楚何时变量仍然有用。如果在这段时间内有一个寄存器可用,它可能最终使用这个寄存器来存储变量

但是,在附加了调试器之后,它可能会决定改用内存位置,因为生存期已发生足够的变化,因此寄存器无法用于该部分代码

CPU的浮点寄存器比相应的浮点存储格式具有更高的精度,这意味着,一旦您从寄存器中取出一个值并将其存储到内存中,或者只是将其一直存储在内存中,您将体验到更低的精度

发布版本和调试版本之间的差异最终可能会决定这些事情,调试器的存在也会如此

此外,不同的.NET运行时版本之间可能存在差异,这可能会影响这一点



正确编写浮点代码需要对您正在尝试执行的操作以及机器和平台的各个部分将如何进行干扰有深入的了解。我会尽量避免编写这样的代码。

执行不会改变,至少不会以您认为的方式改变。
dblMax*1000的结果是什么(∞) ? 如果你分开你会得到什么∞ 1800年?@PanagiotisKanavos我对无限的结果并不感到惊讶。我只是惊讶于同一版本根据我是否调试它而打印出不同的结果。如果我说我还不能复制它,你会感到惊讶吗?事实上,我会感到惊讶(假设你已经尝试过)。我在VS 2010 Professional中的一个新c#console应用程序中运行了这段代码。@PanagiotisKanavos,我使用的是VS2013,.net 4.6.1,我可以重现这个问题……但是为什么发布版本在使用F5或Ctrl F5启动时会有不同的输出?这是另一个问题-无论发生什么,乘法都应该产生无穷大发生在那之后。除非你发现一台没有安装.NET 4.5的计算机,否则就不可能复制。OP虽然使用VS 2010和.NET 2.0或4.0,但它们都非常非常古老versions@wklCTRL F5将在没有调试器的情况下运行应用程序。F5将在发布模式下进行调试。@NicoRiff完全正确。因此,两者都在发布模式下运行。但仍然它们产生不同的输出。调试器将人为延长局部变量的生存期,以确保您可以在不同点检查它们,这可能会将值的存储位置从寄存器(精度较高)更改为内存位置(精度较低)。