UPDATE (12/17/2007): My blog has moved. This post is now located at:
http://jason.whitehorn.ws/2007/06/06/Tail-Recursion-Revisited.aspx
A year ago I blogged about
Tail Recursion in C# on .NET 2.0. With the public beta of .NET 3.5 now available, I decided to retry my little experiment.
For the experiment I used Beta 1 of .NET 3.5 (version 3.5.20404), which you can get
from here. Using the supplied compiler, I compiled the following C# code:
public class TailTest{
public static void Main(){
TailTest f = new TailTest();
f.DoTail(0);
}
public void DoTail(int n){
int v = n + 1;
System.Console.WriteLine(v);
DoTail(v);
}
}
Just running the produced EXE is enough to determine that even with the newest version of Microsoft's compiler, the program has not been optimized for tail recursion. Just to confirm this findings, I went ahead and decompiled the EXE to
IL anyway.
.class public auto ansi beforefieldinit TailTest
extends [mscorlib]System.Object
{
.method public hidebysig specialname rtspecialname instance void .ctor() cil managed
{
.maxstack 8
L_0000: ldarg.0
L_0001: call instance void [mscorlib]System.Object::.ctor()
L_0006: ret
}
.method public hidebysig instance void DoTail(int32 n) cil managed
{
.maxstack 2
.locals init (
[0] int32 num)
L_0000: nop
L_0001: ldarg.1
L_0002: ldc.i4.1
L_0003: add
L_0004: stloc.0
L_0005: ldloc.0
L_0006: call void [mscorlib]System.Console::WriteLine(int32)
L_000b: nop
L_000c: ldarg.0
L_000d: ldloc.0
L_000e: call instance void TailTest::DoTail(int32)
L_0013: nop
L_0014: ret
}
.method public hidebysig static void Main() cil managed
{
.entrypoint
.maxstack 2
.locals init (
[0] class TailTest test)
L_0000: nop
L_0001: newobj instance void TailTest::.ctor()
L_0006: stloc.0
L_0007: ldloc.0
L_0008: ldc.i4.0
L_0009: callvirt instance void TailTest::DoTail(int32)
L_000e: nop
L_000f: ret
}
}
From my
previous discussion, we can see that the resulting IL lacks the "tail.". With all the innovation in C# for the upcoming release of .NET 3.5, I was hoping that the outcome from my experiment would have been different.