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

wkl*_*wkl 0 c# debugging visual-studio-2010

考虑以下简单程序:

var dblMax = Double.MaxValue;

var result = (dblMax * 1000) / 1800;
Console.WriteLine(result);
Run Code Online (Sandbox Code Playgroud)

当我在调试模式下构建它并运行 (Ctrl+F5) 或调试 (F5) 时,它会打印9.987140856842E+307.

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

我知道这种差异是由于在发布模式下完成的一些编译器优化造成的。

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

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

编辑:

我不问为什么调试模式和发布模式会产生不同的结果。我想知道为什么发布模式会根据我是否调试 (F5) 或不调试 (Ctrl+F5) 产生不同的结果。

ang*_*son 5

调试时 JITter 的行为不同。

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

JITer 非常清楚地知道什么时候一个变量仍然有用。如果在那段时间内有一个寄存器可用,它最终可能会使用这个寄存器来存储变量。

但是,在附加调试器的情况下,它可能会决定改为使用内存位置,因为生命周期发生了足够的变化,以至于该部分代码无法使用寄存器。

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

RELEASE 和 DEBUG 构建之间的差异最终会决定这些事情,调试器的存在也是如此。

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


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