5

我看到了一些关于 C# 中缺少尾调用优化的问题,据说这使得该语言不适合递归算法实现。然而,这引出了一个问题,我们如何进行尾调用优化,并且在引发异常或可以使用反射来检查调用堆栈并对其采取行动时仍然提供合理的堆栈跟踪。

4

1 回答 1

6

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.

于 2010-10-21T21:37:28.187 回答