偶然明白了Release和Debug的一點區別

來源:互聯網
上載者:User

在這之前,讓我說出Release和Debug編譯出的軟體的區別,我還真的只能說寫套話,沒有什麼深入的瞭解和實際的感觸。最近研究MSIL,在寫一段C#代碼出現了點手誤。就是這個失誤,透過MSIL,讓我從一個方面瞭解了二者的區別。

源碼如下:

 

            int x, y, z;
            string s;

            Console.WriteLine("Enter x:");
            s = Console.ReadLine();
            x = Int32.Parse(s);

            Console.WriteLine("Enter y:");
            s = Console.ReadLine();
            y = Int32.Parse(s);

            if (x < y)
                z = x;
            else
                z = y;

            Console.WriteLine("{0:d}, z");

很容易看到,手誤在最後一行,我的本意是輸出z的值。由於引號的位置錯了,這樣的輸出就變成了:{0:d}, z。這樣if...else一段根本是沒用的。

Debug編譯出來的MSIL代碼是這樣的:

.method private hidebysig static void  Main(string[] args) cil managed
...{
  .entrypoint
  // Code size       80 (0x50)
  .maxstack  2
  .locals init ([0] int32 x,
           [1] int32 y,
           [2] int32 z,
           [3] string s,
           [4] bool CS$4$0000)
  IL_0000:  nop
  IL_0001:  ldstr      "Enter x:"
  IL_0006:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_000b:  nop
  IL_000c:  call       string [mscorlib]System.Console::ReadLine()
  IL_0011:  stloc.3
  IL_0012:  ldloc.3
  IL_0013:  call       int32 [mscorlib]System.Int32::Parse(string)
  IL_0018:  stloc.0
  IL_0019:  ldstr      "Enter y:"
  IL_001e:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_0023:  nop
  IL_0024:  call       string [mscorlib]System.Console::ReadLine()
  IL_0029:  stloc.3
  IL_002a:  ldloc.3
  IL_002b:  call       int32 [mscorlib]System.Int32::Parse(string)
  IL_0030:  stloc.1
  IL_0031:  ldloc.0
  IL_0032:  ldloc.1
  IL_0033:  clt
  IL_0035:  ldc.i4.0
  IL_0036:  ceq
  IL_0038:  stloc.s    CS$4$0000
  IL_003a:  ldloc.s    CS$4$0000
  IL_003c:  brtrue.s   IL_0042
  IL_003e:  ldloc.0
  IL_003f:  stloc.2
  IL_0040:  br.s       IL_0044
  IL_0042:  ldloc.1
  IL_0043:  stloc.2
  IL_0044:  ldstr      "{0:d}, z"
  IL_0049:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_004e:  nop
  IL_004f:  ret
} // end of method Program::Main

Release編譯出來的就簡單多了,而且也沒有nop操作:

.method private hidebysig static void  Main(string[] args) cil managed
...{
  .entrypoint
  // Code size       61 (0x3d)
  .maxstack  2
  .locals init ([0] int32 x,
           [1] int32 y,
           [2] string s)
  IL_0000:  ldstr      "Enter x:"
  IL_0005:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_000a:  call       string [mscorlib]System.Console::ReadLine()
  IL_000f:  stloc.2
  IL_0010:  ldloc.2
  IL_0011:  call       int32 [mscorlib]System.Int32::Parse(string)
  IL_0016:  stloc.0
  IL_0017:  ldstr      "Enter y:"
  IL_001c:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_0021:  call       string [mscorlib]System.Console::ReadLine()
  IL_0026:  stloc.2
  IL_0027:  ldloc.2
  IL_0028:  call       int32 [mscorlib]System.Int32::Parse(string)
  IL_002d:  stloc.1
  IL_002e:  ldloc.0
  IL_002f:  ldloc.1
  IL_0030:  pop
  IL_0031:  pop
  IL_0032:  ldstr      "{0:d}, z"
  IL_0037:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_003c:  ret
} // end of method Program::Main

我一開始使用Release編譯的,感覺很奇怪,明顯if...else一段就沒有編譯。我想怪哉了。然後運行了一下,發現結果是“{0:d},z"。發現了最後一行的手誤,這一手誤直接導致if...else一段成了垃圾代碼。然後用F11單步跟蹤,if...else那段代碼根本就是整體跳過。於是換Debug模式編譯,發現編譯出來的MSIL的if...else是完整的,單步跟蹤也跟進去了。恍然大悟。。。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.