您的位置:首页 > 其它

偶然明白了Release和Debug的一点区别

2008-05-10 15:47 399 查看
在这之前,让我说出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是完整的,单步跟踪也跟进去了。恍然大悟。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: