как возможна оптимизация хвостовой рекурсии в C # при возврате трассировки стека при возникновении исключения - PullRequest
5 голосов
/ 22 октября 2010

Я видел несколько вопросов, касающихся отсутствующей оптимизации хвостовых вызовов в C #, якобы делающей язык плохо подходящим для реализации рекурсивных алгоритмов.это, однако, порождает вопрос: как мы можем выполнить оптимизацию хвостовых вызовов и при этом обеспечить разумную трассировку стека при возникновении исключений или когда отражение может использоваться для проверки стека вызовов и воздействия на него.

1 Ответ

5 голосов
/ 22 октября 2010

Ну, это имеет значение, только если вы ожидаете получить точную трассировку стека:)

Оптимизация вызовов в хвосте - это не единственные вещи, которые могут уничтожить трассировку стека - самый простой пример - встраивание, которое можетконечно влияет на вещи.По сути, все, что зависит от точности трассировки стека, представляет собой небольшой риск.

Вот очень простой пример именно этой проблемы:

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();
    }
}

Сборка и запуск без отладчика, и вы можете получить это:

at Program.Call3()
at Program.Main(String[] args)

В общем, будьте осторожны в том, что вы делаете со следами стека.

...