When something looks impossible

Recently one person asked me to check following code:

1. if (s.Length > 1)
2. {
3.     string numberString = s.Substring(0, 1);
4.     result.Text = s.Substring(pos + 1, s.Length - pos);
5. }

When that person runs this code, it throws ArgumentOutOfRangeException exception on line #3. But as you can see, first line checks that string is not empty and s.Substring(0, 1) should never throw any exception. And looks like that person was correct.

Then I found that this code compiled for .NET Core 3.1. I tried to increase version to .NET 5 and problem is still there. I put breakpoint to line 3 and run application. When application stopped on that line, I tried to use Quick Watch to evaluate result of s.Substring(0, 1). And it evaluates correctly. Quite strage, but I know that evaluation works a bit different from normal compilation and certain optimization may not apply. Then I added following line before line #3:
Debug.WriteLine(s.Substring(0, 1));

And that line works correctly as well. And then I realized that all this time, that person used Release configuration. As soon as switch back to Debug everything starts working and application correctly throws ArgumentOutOfRangeException exception on line #4. And that line was source of problem in first place. It just Release does serious optiomizations and sometimes messes with line numbers.

I hope it helps someone.