如果语句出现甚至当条件计算为假时要评估 [英] If statement appears to be evaluating even when condition evaluates to false

查看:171
本文介绍了如果语句出现甚至当条件计算为假时要评估的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

深夜工作,昨晚我们试图弄清楚为什么有些是失败。验证检查是失败时,它应该不会迟到了。

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆