2010-03-22 174 views
1

下面的C#-snippet:變量比較

var x = 1; 
var y = 1; 
if (x == y) 
    Console.Write("True"); 

生成此MSIL:

.locals init (
      [0] int32 x, 
      [1] int32 y, 
      [2] bool CS$4$0000) 
L_0000: nop 
L_0001: ldc.i4.1 
L_0002: stloc.0 
L_0003: ldc.i4.1 
L_0004: stloc.1 
L_0005: ldloc.0 
L_0006: ldloc.1 
L_0007: ceq 
L_0009: ldc.i4.0 
L_000a: ceq 
L_000c: stloc.2 
L_000d: ldloc.2 
L_000e: brtrue.s L_001b 
L_0010: ldstr "True" 
L_0015: call void [mscorlib]System.Console::Write(string) 
L_001a: nop 
L_001b: ret 

爲什麼有兩種ceq電話?

由於

+0

檢查發佈模式。 – SLaks 2010-03-22 15:07:47

+0

啊,這解釋了很多令我頭腦發生混亂的事情。謝謝。 – alexn 2010-03-22 15:09:56

回答

2

第二ceq操作碼進行比較第一個0的結果。 (false

然後將此結果放入變量中,從變量中加載,如果它是true,則跳過WriteLine調用。

我會假設發佈模式生成更高效的代碼,但我懶得檢查。

+0

是的,從我所知道的情況來看,釋放模式會生成更有效的il-code。甚至沒有電話給'ceq'。這是因爲編譯器知道x和z是常量嗎? – alexn 2010-03-22 15:14:39

+0

@alexn:正確。編譯器優化了常量比較。如果你不想要,你可以編寫'Math.Max(1,1)',這不是一個編譯時常量。 – SLaks 2010-03-22 15:24:33

2

關於值與ceq比較從MSDN

如果它們相等,則整數值1(INT32)被壓入計算堆棧;否則將0(int32)壓入評估堆棧。

第二個ceq檢查第一次比較是否失敗,如果是,則跳轉到出口點。

+0

感謝您的回答。 – alexn 2010-03-22 15:16:36