[英]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.