C # Compiler Optimization - Catch Only Containing Cast

I would expect the following two implementations MyMethod

to behave as exactly . They? If not, this may already be my wrong assumption:

Firstly:

public int MyMethod(int x)
{
    try
    {
        return x + 8;
    }
    catch
    {
        throw;
    }
}

      

Secondly:

public int MyMethod(int x)
{
    return x + 8;
}

      

So, I would suggest that the compiler optimizes this, i.e. will remove the unnecessary try / catch block of the first implementation (in Release mode). As it turns out, this is not the case - here is the generated IL for two code samples:

Firstly:

.method public hidebysig instance int32  MyMethod(int32 x) cil managed
{
  // Code size       11 (0xb)
  .maxstack  2
  .locals init ([0] int32 CS$1$0000)
  .try
  {
    IL_0000:  ldarg.1
    IL_0001:  ldc.i4.8
    IL_0002:  add
    IL_0003:  stloc.0
    IL_0004:  leave.s    IL_0009
  }  // end .try
  catch [mscorlib]System.Object 
  {
    IL_0006:  pop
    IL_0007:  rethrow
  }  // end handler
  IL_0009:  ldloc.0
  IL_000a:  ret
} // end of method MyClass::MyMethod

      

Secondly:

.method public hidebysig instance int32  MyMethod(int32 x) cil managed
{
  // Code size       4 (0x4)
  .maxstack  8
  IL_0000:  ldarg.1
  IL_0001:  ldc.i4.8
  IL_0002:  add
  IL_0003:  ret
} // end of method MyClass::MyMethod

      

Can someone shed some light on this? Is there a difference in the behavior of the two implementations (side effects?)? Can the compiler optimize the code, but just not? Thank!

+3


source to share


2 answers


A lot of optimization is done by JITter and only some optimization by the compiler generating the IL. So I couldn't tell what was actually compiled to machine code at the time the program was run (maybe you can debug).
You can find information in the post: http://blogs.msdn.com/b/ericlippert/archive/2009/06/11/what-does-the-optimize-switch-do.aspx , written by one of the C # compiler commands ...
It says,
"The / optimize flag doesn't change a huge amount of our emit and generate logic. We try to always generate simple, testable code and then rely on jitter to do the heavy lifting of optimizations when generating real machine code."

You can also find information from the link in some cases that are actually optimized for IL code generation.

Refresh



There is a performance test for consequences in response:
what would be empty to catch and throw a block?
it confirms that it is not optimized.

And when asked if the code could be deleted, there was a discussion: Is it possible to delete an empty catch with a throw?

+2


source


The compiler cannot assume that the try / catch block is unnecessary in this case.

If there is any code inside, chances are that it will throw an exception. For example:

  • Operator
  • "+" can be overwritten in one of the objects and the exception ...
  • the constructor of the object that will be returned from the "try" block may throw an exception ...


Even if you are not "handling" the Exception object caught on the catch, many things happen in the background. For example, the constructor of the Exception object is launched (the compiler cannot be sure that there is or is not something important implemented).

As you can see, even one (almost empty) try / catch block is not so trivial from the compiler's point of view.

0


source







All Articles