Take the 2-minute tour ×

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 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'            

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());
/* */
        (lastModified != DateTime.MaxValue))
        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.

This morning, I recorded a video.

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.

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

Edit: Here is the IL. I don't think there's anything wrong with it because it decompiles to the correct C#:


Confirmed as a bug by Microsoft, to be fixed in the next release.

share|improve this question
Great Video! Havn't seen such behavior for a long time. I once had the same problem (but in Java). Adding a single "System.out.println();" solved it for me as well. This is really strange... –  Christian May 19 '11 at 7:13
@Porges Can we get the MSIL (the .NET assembly, not the x86 assembly :))? You can use the .NET Reflector to get at the specific method you want. –  pickypg May 25 '11 at 17:36
@pickypg: I've added it. I don't think there's anything wrong with it since it decompiles to the correct C# code (I haven't gone through it by hand though). –  Porges May 25 '11 at 22:18
@ohmantics: can you please explain why you're removing the assembly tag? I have linked x86 assembly code contained in this question... –  Porges May 27 '11 at 2:24
I've filed a bugreport with MS connect: connect.microsoft.com/VisualStudio/feedback/details/671105/… –  CodesInChaos May 27 '11 at 11:23
show 2 more comments

5 Answers

up vote 6 down vote accepted

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))) 
             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

share|improve this answer
Wow, thanks! I didn't think it would be possible to reproduce it outside the context of our library :) –  Porges May 28 '11 at 2:08
RE: Update - I thought I had mentioned this in the original post, but I seem to have edited it out. I'll add a little note. –  Porges May 30 '11 at 22:07
They've (finally) replied to the bug and state it will be fixed in the next framework release. I've checked again and it doesn't seem to be in the recent KB2468871/KB2533523 release, so hopefully it will be the next one. Marking this as the answer. –  Porges Aug 18 '11 at 0:29
add comment

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?

share|improve this answer
The x86 disassembly is linked already? –  Porges May 26 '11 at 0:24
So it is - sorry. Unfortunately, I don't have time to analyze it right now, but I'll take a look again tomorrow if no one else has. –  500 - Internal Server Error May 26 '11 at 0:51
add comment

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! }
share|improve this answer
I see no boxing here. –  CodesInChaos May 29 '11 at 19:00
add comment

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.

share|improve this answer
This behaviour happens whether or not I attach the debugger (the first output is from a run without the debugger attached). I just attached to be able to break there and make sure. –  Porges May 19 '11 at 7:22
I actually didn't attach the debugger until this morning, so the first output, the "fix", and the reproduction when "fix" was removed all were without the debugger interfering. –  Porges May 19 '11 at 7:28
add comment

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
share|improve this answer
add comment

Your Answer


