Watch out for those Nulls.
Bill McCarthy found a very weird bug today. It seems that if you craft some code just right and do a release build, then you can get your code to throw a NullReferenceException when it clearly shouldn't have.
He first found the bug in VB and presumed it was a VB compiler issue, but after a bit of playing we were able to come up with the same issue in C# - which leads us to believe there must be something up with the JITter. So of course, in true Bill style, he's only publicly posted the C# example :)
So, to be fair, here's the VB version of the same thing.
Sub Main()
Console.WriteLine("starting")
Test(Nothing)
Console.WriteLine("finished")
End Sub
Private Sub Test(ByVal x As String)
For j As Int32 = 0 To 10
If String.IsNullOrEmpty(x) Then
'TODO
End If
Next
End Sub
If you compile this code in Release mode and run it from the command line (no F5 in visual studio!) then this code throws a NullReferenceException. Because it's a release build, there's no debug info to find out exactly where it broke - just somewhere in the test method. Because my debugging skills boil down to either setting a break point or adding a few Debug.Print() statements, I can't really debug this - adding a console.writeline() to the test method stops it from breaking.
I've had a look at the IL that's been spat out in Reflector, and I honestly can't see anything going wrong here. What's really strange is that to get a NullReferenceException I can only see two places where it could happen - the first inside IsNullOrEmpty where there's a call to get the length of the passed in string, but only after making sure it isn't null first. The second feels to me like where it's dying, but I have no idea why - The IsNullOrEmpty call on the global String object is falling over because the global String object is Null. But how could that happen?
This one has me quite confused - but very intrigued :)