Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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# supposedly 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.

like image 938
Carlo V. Dango Avatar asked Oct 21 '10 21:10

Carlo V. Dango


1 Answers

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.

like image 182
Jon Skeet Avatar answered Sep 27 '22 16:09

Jon Skeet