簡體   English   中英

為什么我需要檢查大於Int32.MaxValue?

[英]Why would I need to check for greater than Int32.MaxValue?

我在ac#class library project(.net 4)上使用Visual Studio 2010 SP1 Ultimate,我很好奇......

鑒於此方法:

public void DoSomethingBrilliant(int input)
{
    if (input == int.MaxValue)
        throw new ArgumentOutOfRangeException("input");

    input++;

    Console.WriteLine(input);
}

我從代碼分析中收到此警告:

CA2233:Microsoft.Usage:更正'Test.DoSomethingBrilliant(int)'中操作'input + 1'的潛在溢出。

我心里想,這有點奇怪,因為我檢查input++操作不會因為在開始時拋出那個時髦的異常而溢出但是我改為:

public void DoSomethingBrilliant(int input)
{
    if (input >= int.MaxValue)
        throw new ArgumentOutOfRangeException("input");

    input++;

    Console.WriteLine(input);
}

果然警告消失了。

現在我的小腦子都搞糊塗了,因為我得到一個int作為參數,為什么要檢查它是否大於允許整數提供任何值的最大值?

然后我回到原來的代碼並切換到調試,並在沒有警告的情況下構建它! Curiouser和curioser ......

我檢查了調試和發布之間的差異,發現如果我勾選Optimize代碼選項,代碼分析的警告會立即彈回。

因此,優化會導致我需要檢查大於int.MaxValue的內容 咦? 為什么? 我超級密集嗎? 優化完成的是什么意味着我可能會獲得比int.MaxValue更大的int傳遞給接受int的方法?

或者,這只是代碼分析功能中的一個錯誤嗎?

更新

這是“未經優化”版本的IL(代碼分析正確):

.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

這里是優化版本(它出錯了):

.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

在投擲操作之前我看到了一堆額外的電話,但我會說實話 - 我不知道他們做了什么!

或者,這只是代碼分析功能中的一個錯誤嗎?

看起來像。 說實話非常令人驚訝 - 讓這種代碼分析變得完美是非常棘手的。 鑒於任何特定的int 都不能大於int.MaxValue>===肯定是等價的。

請參閱以下代碼片段:

if (x == int.MaxValue) return;
// x != int.MaxValue

if (x >= int.MaxValue) return;
// x < int.MaxValue

// x < int.MaxValue
// rewrite
// x + 1 <= int.MaxValue
x++;
// x <= int.MaxValue

x ++的后置條件顯示(通過推導)前提條件必須是:

x < int.MaxValue 

只有在您檢查時才能建立:

x >= int.MaxValue

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM