Software Is Hardwork

ISimplicityAffinative: The endless pursuit of anti-complexity.
The technology-centric blog of D. P. Bullington.

Email D. P. Bullington View D. P. Bullington\ Follow D. P. Bullington on Twitter Get Software Is Hardwork code on CodePlex

Blog Post(s)

C# Compiler and Infinite Iterating Methods
Friday, October 5, 2007

A friend of mine (and fellow C# coder) asked me to consider the following code:

public int ExampleMethodA()
{
    while(true)
    {
    }
}

public int ExampleMethodB()
{
    const bool loop = true;

    while (loop)
    {
    }
}

public int ExampleMethodC()
{
    bool loop = true;

    while (loop)
    {
    }

    return 0;
}
He thought it was odd that the C# compiler (.NET Framework 3.0) willingly compiles example methods A and B, but complains (as expected) on method C until you explicitly return a value. I presented a theory that the C# compiler must optimize away the need for the return statements in example methods A and B, but not C. To dive deeper and prove my hypothesis, I dusted off trusty old ILDASM.exe and examined the MSIL generated in all three cases.
.method public hidebysig instance int32  ExampleMethodA() cil managed
{
    // Code size       9 (0x9)
    .maxstack  1
    .locals init ([0] int32 CS$1$0000,
           [1] bool CS$4$0001)
    IL_0000:  nop
    IL_0001:  br.s       IL_0005
    IL_0003:  nop
    IL_0004:  nop
    IL_0005:  ldc.i4.1
    IL_0006:  stloc.1
    IL_0007:  br.s       IL_0003
} // end of method Program::ExampleMethodA


.method public hidebysig instance int32  ExampleMethodB() cil managed
{
    // Code size       9 (0x9)
    .maxstack  1
    .locals init ([0] int32 CS$1$0000,
           [1] bool CS$4$0001)
    IL_0000:  nop
    IL_0001:  br.s       IL_0005
    IL_0003:  nop
    IL_0004:  nop
    IL_0005:  ldc.i4.1
    IL_0006:  stloc.1
    IL_0007:  br.s       IL_0003
} // end of method Program::ExampleMethodB


.method public hidebysig instance int32  ExampleMethodC() cil managed
{
    // Code size       18 (0x12)
    .maxstack  1
    .locals init ([0] bool loop,
           [1] int32 CS$1$0000,
           [2] bool CS$4$0001)
    IL_0000:  nop
    IL_0001:  ldc.i4.1
    IL_0002:  stloc.0
    IL_0003:  br.s       IL_0007
    IL_0005:  nop
    IL_0006:  nop
    IL_0007:  ldloc.0
    IL_0008:  stloc.2
    IL_0009:  ldloc.2
    IL_000a:  brtrue.s   IL_0005
    IL_000c:  ldc.i4.0
    IL_000d:  stloc.1
    IL_000e:  br.s       IL_0010
    IL_0010:  ldloc.1
    IL_0011:  ret
} // end of method Program::ExampleMethodC

Interestingly enough, example methods A and B emit the same MSIL, and they have no RET instruction. On the other hand, example method C has slightly differing MSIL, due to a non-constant looping condition and it does have a RET instruction. Theory confirmed: the C# compiler optimizes away the need for return statements if it can be determined the method will never actually return.

0 comments:

Blog Archive

Labels

Blog List

Speaking Enagements

  • 12/8/2009 | Hampton Roads .NET Users Group | Cheaspeake, VA | Topic TBD
  • 07/16/2009 | Charlottesville .NET Users Group | Charlottesville, VA | Debugging on the Windows Platform
  • 05/23/2008 | NoVa CodeCamp 2009.01 | Reston, VA | Going Proxy-less - The WCF Proxy Factory
  • 04/25/2009 | Richmond Code Camp 2009.1 | Richmond, VA | Software Programmer to Software Engineer: Concepts to Span the Divide
  • 02/05/2009 | Richmond .NET Users Group | Richmond, VA | Debugging on the Windows Platform
  • 10/04/2008 | Richmond Code Camp 2008.2 | Richmond, VA | Going Proxy-less - The WCF Proxy Factory

Disclaimer

© D. P. Bullington, all rights reserved. Everything posted on this blog is my personal opinion and does not necessarily represent the views of my employer or its clients.