title: Why would I need to check for greater than Int32.MaxValue?
body: <p>I am using Visual Studio 2010 SP1 Ultimate on a c# class library project (.net 4) and I am curious about something...</p>
  
  <p>Given this method:</p>
  
  <pre><code>public void DoSomethingBrilliant(int input)
  {
      if (input == int.MaxValue)
          throw new ArgumentOutOfRangeException("input");
  
      input++;
  
      Console.WriteLine(input);
  }
  </code></pre>
  
  <p>I get this warning from code analysis:</p>
  
  <blockquote>
    <blockquote>
      <p>CA2233 : Microsoft.Usage : Correct the potential overflow in the operation 'input+1' in 'Test.DoSomethingBrilliant(int)'.    </p>
    </blockquote>
  </blockquote>
  
  <p>I thought to myself, that is a bit odd since I am checking that the <code>input++</code> operation won't overflow by throwing that snazzy exception at the beginning but I changed it to this:</p>
  
  <pre><code>public void DoSomethingBrilliant(int input)
  {
      if (input &gt;= int.MaxValue)
          throw new ArgumentOutOfRangeException("input");
  
      input++;
  
      Console.WriteLine(input);
  }
  </code></pre>
  
  <p>and sure enough the warning went away.  </p>
  
  <p>Now my little brain is all confused because given I am getting an <a href="http://msdn.microsoft.com/en-us/library/system.int32.aspx" rel="noreferrer">int</a> as an argument why would checking to see if it is greater than the maximum value allowed for an integer ever provide any value? </p>
  
  <p>Then I went back to the original bit of code and switched to debug and it built without the warning!  Curiouser and curioser...</p>
  
  <p>I checked the differences between debug and release and found that if I tick the <em>Optimize code</em> option the warning from code analysis pops right back up.</p>
  
  <p>So the optimization results in something that means I need to check for greater than <a href="http://msdn.microsoft.com/en-us/library/system.int32.maxvalue.aspx" rel="noreferrer">int.MaxValue</a>.  Huh?  Why?  Am I being super dense?  What has the optimization done that means I might get an int bigger than <a href="http://msdn.microsoft.com/en-us/library/system.int32.maxvalue.aspx" rel="noreferrer">int.MaxValue</a> passed into a method accepting an <a href="http://msdn.microsoft.com/en-us/library/system.int32.aspx" rel="noreferrer">int</a>?</p>
  
  <p>Or, is this just a bug in the code analysis feature?</p>
  
  <p><strong>Update</strong></p>
  
  <p>Here is the IL for the "unoptimized" version (where the code analysis gets it right):</p>
  
  <pre><code>.method public hidebysig instance void  DoSomethingBrilliant(int32 input) cil managed
  {
    // Code size       40 (0x28)
    .maxstack  2
    .locals init ([0] bool CS$4$0000)
    IL_0000:  nop
    IL_0001:  ldarg.1
    IL_0002:  ldc.i4     0x7fffffff
    IL_0007:  ceq
    IL_0009:  ldc.i4.0
    IL_000a:  ceq
    IL_000c:  stloc.0
    IL_000d:  ldloc.0
    IL_000e:  brtrue.s   IL_001b
    IL_0010:  ldstr      "input"
    IL_0015:  newobj     instance void [mscorlib]System.ArgumentOutOfRangeException::.ctor(string)
    IL_001a:  throw
    IL_001b:  ldarg.1
    IL_001c:  ldc.i4.1
    IL_001d:  add
    IL_001e:  starg.s    input
    IL_0020:  ldarg.1
    IL_0021:  call       void [mscorlib]System.Console::WriteLine(int32)
    IL_0026:  nop
    IL_0027:  ret
  } // end of method Test::DoSomethingBrilliant
  </code></pre>
  
  <p>and here it is for the optimized version (where it gets it wrong):</p>
  
  <pre><code>.method public hidebysig instance void  DoSomethingBrilliant(int32 input) cil managed
  {
    // Code size       31 (0x1f)
    .maxstack  8
    IL_0000:  ldarg.1
    IL_0001:  ldc.i4     0x7fffffff
    IL_0006:  bne.un.s   IL_0013
    IL_0008:  ldstr      "input"
    IL_000d:  newobj     instance void [mscorlib]System.ArgumentOutOfRangeException::.ctor(string)
    IL_0012:  throw
    IL_0013:  ldarg.1
    IL_0014:  ldc.i4.1
    IL_0015:  add
    IL_0016:  starg.s    input
    IL_0018:  ldarg.1
    IL_0019:  call       void [mscorlib]System.Console::WriteLine(int32)
    IL_001e:  ret
  } // end of method Test::DoSomethingBrilliant
  </code></pre>
  
  <p>I see a bunch of extra calls before the throw operation but I am going to be honest - I have no idea what they do!</p>