Suppose I have the following code:
public class Class1
{
private Class2 obj;
public void MethodA()
{
var class2 = new Class2();
class2.PropertyI = 2;
obj = MethodB(class2);
}
public Class2 MethodB(Class2 class2)
{
return class2;
}
}
public class Class2
{
public int PropertyI { get; set; }
}
The generated IL code from compiling with Visual Studio 2010 as a .NET 2.0 assembly is the following:
.method public hidebysig instance void MethodA() cil managed
{
.maxstack 3
.locals init (
[0] class ClassLibrary1.Class2 class2)
L_0000: nop
L_0001: newobj instance void ClassLibrary1.Class2::.ctor()
L_0006: stloc.0
L_0007: ldloc.0
L_0008: ldc.i4.2
L_0009: callvirt instance void ClassLibrary1.Class2::set_PropertyI(int32)
L_000e: nop
L_000f: ldarg.0
L_0010: ldarg.0
L_0011: ldloc.0
L_0012: call instance class ClassLibrary1.Class2 ClassLibrary1.Class1::MethodB(class ClassLibrary1.Class2)
L_0017: stfld class ClassLibrary1.Class2 ClassLibrary1.Class1::obj
L_001c: ret
}
.method public hidebysig instance class ClassLibrary1.Class2 MethodB(class ClassLibrary1.Class2 class2) cil managed
{
.maxstack 1
.locals init (
[0] class ClassLibrary1.Class2 CS$1$0000)
L_0000: nop
L_0001: ldarg.1
L_0002: stloc.0
L_0003: br.s L_0005
L_0005: ldloc.0
L_0006: ret
}
My questions are the following:
nop
code between L_0006
and L_0007
?
L_0001
to L_0006
are distinct from L_0007
to L_0009
, why is there no nop
opcode?L_0003
necessary?The C# compiler emits a NOP instruction at a curly brace. Which makes it a lot easier to set breakpoints in your code. The debugger only permits setting a breakpoint on code and a curly brace doesn't normally produce any code. So this is just a simple debugging aid, these NOPs won't get generated in the release build.
The BR.S instruction is a minor flaw in the compiler, it doesn't have a peephole optimizer to get rid of these kind of extraneous instructions. In general, it is not the job of the C# compiler to optimize code, that's done by the jitter. Which will readily and easily remove the instruction.
All of what you see is because you're compiling in Debug mode. The redundant jumps and nops are disabled optimization passes as well as debugging support (I believe).
Compile in Release mode.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With