如果语句出现甚至当条件计算为假时要评估 [英] If statement appears to be evaluating even when condition evaluates to false
问题描述
深夜工作,昨晚我们试图弄清楚为什么有些是失败。验证检查是失败时,它应该不会迟到了。
Late At Work last night, we were trying to figure out why something was failing. A validation check was failing when it shouldn't have been.
我们结束了添加打印语句来此code(为了从反射器拆开,检查code,实际上我们所写的东西):
We ended up adding a print statement to this code (disassembled from Reflector in order to check that the code was actually what we had written):
public static string Redacted(string name, DateTime lastModified)
{
long ticks = lastModified.Ticks;
if ((ticks != (ticks - (ticks % 10000L))) &&
(lastModified != DateTime.MaxValue))
{
Log.Debug(string.Format("Last Modified Date = '{0}'. Ticks = '{1}'. TicksCalc = '{2}'",
lastModified.ToString("dd/MM/yyyy hh:mm:ss.fff"),
ticks, ticks - (ticks % 10000L)));
它印(格式化):
It printed (reformatted):
Last Modified Date = '22/03/2011 12:16:22.000'.
Ticks = '634363497820000000'.
TicksCalc = '634363497820000000'
但条件是,蜱
(这等于蜱上面印)不等于(蜱 - (蜱% 10000))
(它等于TicksCalc)! 634363497820000000!= 634363497820000000?!
But the condition is that "ticks
" (which is equal to Ticks printed above) is not equal to "(ticks - (ticks % 10000))
" (which is equal to TicksCalc)! 634363497820000000 != 634363497820000000?!
为了确定什么是怎么回事,我们增加了另外两个语句:
In order to determine what is going on here, we added another two statements:
long ticks = lastModified.Ticks;
/* Added following two lines: */
long num2 = ticks - (ticks % 10000L);
Log.Debug((ticks == num2).ToString());
/* */
if ((ticks != (ticks - (ticks % 10000L))) &&
(lastModified != DateTime.MaxValue))
{
Log.Debug(string.Format("Last Modified Date = '{0}'. Ticks = '{1}'. TicksCalc = '{2}'",
lastModified.ToString("dd/MM/yyyy hh:mm:ss.fff"),
ticks, ticks - (ticks % 10000L)));
由于它应该有,这一个印刷真正
(使用相同的值测试时),并没有写在第二行。
As it should have, this one printed true
(when testing with the same value), and didn't write the second line.
感觉有点失落,我们然后再删除了两行,重新编译,重新运行。原来的行为重演。
Feeling a bit lost, we then removed the two lines again, recompiled, and reran. The original behaviour repeated itself.
今天上午,我录的视频。
视频第一击中使用'破'code,然后重建,并使用工作code重新运行该方法断点的所有节目。请注意,即使调试器显示的如果
条件的计算结果为假
,身体还在输入。
The video first of all shows hitting a breakpoint in the method using the 'broken' code, then rebuilding and rerunning using the 'working' code. Note that even though the debugger displays that the if
condition evaluates as to false
, the body is still entered.
我见过的事情发生时,由调试器观察到,由于调试迫使一些东西进行评估之前,但发生这种情况的调试器是否被使用。
I've seen things like this happen before when observed by the debugger, due to the debugger forcing some things to be evaluated, but this happens whether or not the debugger is employed.
此外,这只是发生在释放模式(即与JIT优化启用)。
Furthermore, this only happens in Release mode (i.e. with JIT optimizations enabled).
下面是两个版本的拆解方法:工作,的不工作。我真的不能读取组装,所以我在他们阐明的希望在这里张贴。
Here are the disassembled methods for both versions: working, not working. I can't really read assembly, so am posting them here in the hopes of elucidation.
我希望答案是不是很明显,我已经完全忽略了...!
I hope that the answer isn't something obvious that I've overlooked completely...!
编辑:这是IL。我不认为有什么不对的地方,因为它反编译为正确的C#:
Here is the IL. I don't think there's anything wrong with it because it decompiles to the correct C#:
- Not working
- Working
更新
<一个href=\"https://connect.microsoft.com/VisualStudio/feedback/details/671105/jitter-or-c-compiler-bug#details\"相对=nofollow>确认为微软的错误,将在下一版本。
推荐答案
我尝试了一下用简单的code:
http://nopaste.info/2c99a0e028_nl.html
I experimented a bit with simplified code: http://nopaste.info/2c99a0e028_nl.html
最有趣的变化是:
static readonly long variableZero=0;
const long constZero=0;
public static void Broken2( long ticks2)
{
long ticks = ticks2+variableZero;
if (ticks != (ticks - (ticks % 10000L)))
{
string.Format("Last Modified Date = '{0}'. Ticks = '{1}'. TicksCalc = '{2}'",
"n/A",
ticks, ticks - (ticks % 10000L)).Dump();
}
}
如果我更换 variableZero
与 constantZero
它的工作原理。
If I replace variableZero
with constantZero
it works.
所以我pretty确保它可以是一个抖动或者编译器错误。
So I'm pretty sure it is either a jitter or a compiler bug.
我已经提交了一份bug报告上MS连接:
<一href=\"https://connect.microsoft.com/VisualStudio/feedback/details/671105/jitter-or-c-compiler-bug#details\" rel=\"nofollow\">https://connect.microsoft.com/VisualStudio/feedback/details/671105/jitter-or-c-compiler-bug#details
I've filed a bugreport on MS Connect: https://connect.microsoft.com/VisualStudio/feedback/details/671105/jitter-or-c-compiler-bug#details
更新:只有在没有附加调试器时,会出现奇怪的行为。即当日新优化被启用。所以我pretty确保它是一个抖动的bug。
Update: The strange behavior only occurs if no debugger is attached. i.e. when Jit optimization is enabled. So I'm pretty sure it's a jitter bug.
而对人没有LINQ垫现在有一个简单的C#控制台项目: http://nopaste.info/ 00a0e37328_nl.html
And for people without linq-pad there is now a plain C# console project: http://nopaste.info/00a0e37328_nl.html
这篇关于如果语句出现甚至当条件计算为假时要评估的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!