In IL code, why is there no null operation code in this situation? Why is there a br.s opcode in this situation?

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 as follows:

 .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 as follows:

  • In MethodA, why is there no nop code between L_0006 and L_0007 ?
    • Since L_0001 to L_0006 are different from L_0007 to L_0009 , why is there no nop code?
  • In method B, why is L_0003 required?
+6
source share
2 answers

The C # compiler emits a NOP command in a brace. This greatly simplifies setting breakpoints in your code. The debugger allows you to set a breakpoint on the code, and a curly brace usually does not generate any code. So this is just a simple help for debugging, these NOPs will not be generated in the release build.

The BR.S instruction is a minor flaw in the compiler; it does not have an eye optimizer to get rid of these types of extraneous instructions. In general, the C # compiler should not optimize code made by jitter . Which will easily and easily remove instructions.

+9
source

All you see is what you compile in debug mode. Fallbacks and nops are disabled optimization options, as well as debugging support (I think).

Compile in release mode.

+1
source

All Articles