If statement appears to be evaluating even when condition evaluates to false

前端 未结 5 2008
梦如初夏
梦如初夏 2020-12-28 19:47

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.

We ended up adding a pr

相关标签:
5条回答
  • 2020-12-28 20:25

    I experimented a bit with simplified code: http://nopaste.info/2c99a0e028_nl.html

    The most interesting variation is:

    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(); 
         } 
     }
    

    If I replace variableZero with constantZero it works.


    So I'm pretty sure it is either a jitter or a compiler bug.

    I've filed a bugreport on MS Connect: https://connect.microsoft.com/VisualStudio/feedback/details/671105/jitter-or-c-compiler-bug#details


    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.

    And for people without linq-pad there is now a plain C# console project: http://nopaste.info/00a0e37328_nl.html

    0 讨论(0)
  • 2020-12-28 20:25

    Check out this thread.

    If statement weirdness in Visual Studio 2008

    It comes down to this, you can't trust the debugger all the time.

    To "fix" that if statement, add an empty else {} statement to it. The debugger will work as expected.

    0 讨论(0)
  • That's crazy. Have you tried, for no good reason, to reorder the if statement?

    if (lastModified != DateTime.MaxValue && ticks != (ticks - (ticks % 10000L))
    

    Also, if this doesn't work (as it shouldn't, considering it shouldn't be a problem in the first place), can you show the actual IL for the code in in the problematic form?

    One other thing, couldn't the ticks check be simplified to:

    (ticks % 10000L) != 0
    
    0 讨论(0)
  • 2020-12-28 20:41

    I had something similar a while ago. In my case it had to do with the fact that i was comparing 2 integer values where one value was actually a reference to a boxed integer and the other was a real primitive value.

    The thing is that if you print out the value of the boxed integer and the primitive, they look the same, but comparing them is another thing. You'll get a reference comparison in stead of a value comparison.

    The answer is easy:

    long ticks = lastModified.Ticks;
    long num2 = ticks - (ticks % 10000L);
    if ((ticks != num2) && (lastModified != DateTime.MaxValue))
    { do your thing here! }
    
    0 讨论(0)
  • 2020-12-28 20:43

    That does indeed look like an - ahem - jitterbug. Can you set a break-point on the "if" statement and show us a screenshot of the disassembly view after it hits?

    0 讨论(0)
提交回复
热议问题