我使用Visual Studio 2010 SP1旗艦版在C#類庫項目(.NET 4),我很好奇的東西...爲什麼我需要檢查大於Int32.MaxValue?
鑑於這種方法:
public void DoSomethingBrilliant(int input)
{
if (input == int.MaxValue)
throw new ArgumentOutOfRangeException("input");
input++;
Console.WriteLine(input);
}
我得到這樣的警告代碼分析:
CA2233:Microsoft.Usage:糾正操作 'Test.DoSomethingBrilliant(int)的' '輸入+ 1' 中的可能的溢出。
我心想,這是一個有點奇怪,因爲我檢查了input++
操作不會拋出該異常時髦一開始溢出,但我把它改成這樣:
public void DoSomethingBrilliant(int input)
{
if (input >= int.MaxValue)
throw new ArgumentOutOfRangeException("input");
input++;
Console.WriteLine(input);
}
當然,警告消失了。
現在我的小腦袋全部都感到困惑,因爲我得到一個int作爲一個參數,爲什麼要檢查它是否大於一個整數提供的任何值所允許的最大值?
然後我又回到原來的代碼位置,切換到調試模式,並且沒有警告就編譯出來! curiouser和古董...
我檢查了調試和發佈之間的差異,發現如果我選擇優化代碼選項,代碼分析的警告立即彈出。
因此,優化結果意味着我需要檢查大於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
我看到一堆額外的電話投擲操作之前,但我會說實話 - 我不知道什麼他們是這樣!
代碼分析器可能看到不平等運營商具有比簡單的平等更莊重。當我進行安全檢查時,我當然會試圖削減儘可能多的價值觀。 – bluevector
我感興趣的是爲什麼它會在非優化的「調試」程序集中正確使用它? – kmp
@kmp:不想說。我懷疑'=='是否以某種奇怪的方式進行了優化。你有沒有看過IL? –