Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
C#の末尾呼び出し最適化がいろいろおかしいって話
using System.Diagnostics;
using static System.Console;
class Program
{
static void Main(string[] args)
{
// 末尾再帰の検証 .NET framework 4.6.1 / Release_x64
//A(10000000); // -> StackOverflowException!!!!
//B(10000000); // -> OK!!!!
//C(10000000); // -> ...OK
//D(10000000); // -> Infinite Recursion!!
//E(10000000); // -> StackOverflowException!!!
}
public static int A(int x) // 普通の末尾再帰
{
return (x <= 0) ? x : A(x - 1);
} // StackOverflowする
public static int B(int x) // 普通の末尾再帰の間にWriteLine
{
WriteLine(new StackTrace().FrameCount);
return (x <= 0) ? x : B(x - 1);
} // StackOverflowしない!!!観測者効果かな???
public static int C(int x) // 普通の末尾再帰の間にダミーのnewobj
{
var _ = new object();
return (x <= 0) ? x : C(x - 1);
} // 何故かStackOverflowしない……
private static readonly int z1 = 0;
public static int D(int x) // ただの無限再帰を三項演算子で挟む
{
return (z1 == 0) ? D(x) : D(x);
} // ちゃんと無限ループになる == 末尾呼び出しの最適化が効いてる
private const int z2 = 0;
public static int E(int x) // ただの無限再帰を条件がコンパイル時に確定するような三項演算子で挟む
{
return (z2 == 0) ? E(x) : E(x);
} // StackOverflowする 条件項に true or false でも同様に死亡
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.