how is C# tail recursion optimization possible when a stack trace is returned when an exception is raised
I'be seen a few questions regarding missing tail call optimization in C# supposed开发者_运维技巧ly making the language ill suited for recursive algorithm implementations. this, however,begs the question, how can we do tail call optimizations and still provide sensible stack traces when exceptions are raised or when reflection may be used to inspect the call stack and act upon it.
Well, it only matters if you expect to get an accurate stack trace :)
Tail-call optimizations aren't the only things that can destroy a stack trace - the simplest example is inlining, which can certainly affect things. Basically, anything which relies on the stack trace being accurate is taking a bit of a risk.
Here's a very simple example of exactly that problem:
using System;
using System.Runtime.CompilerServices;
class Program
{
static void Main(string[] args)
{
try
{
Call1();
}
catch (Exception e)
{
Console.WriteLine(e.StackTrace);
}
}
static void Call1()
{
Call2();
}
static void Call2()
{
Call3();
}
[MethodImpl(MethodImplOptions.NoInlining)]
static void Call3()
{
Call4();
}
static void Call4()
{
Call5();
}
static void Call5()
{
throw new Exception();
}
}
Build and run without the debugger, and you may get this:
at Program.Call3()
at Program.Main(String[] args)
Basically, be careful what you do with stack traces.
精彩评论