末尾呼び出しとは、関数A内の末尾で他の関数Bを呼び出することで、
関数Bの呼び出し後、他に処理が存在しない状態を指す。
通常は、関数呼び出しを行うと、呼び出す関数用にスタック領域を消費するが、
末尾呼び出しの場合は、消費されない。
(ex-1)
function foo(n) if n > 0 then return foo(n-1) end end foo(1000000)
(ex-2)
function foo(n) if n > 0 then return (foo(n-1)) end end foo(1000000)
上記はいずれも関数fooを1M回呼び出しているが、
(ex-1)は正常終了するものの、
(ex-2)はStack over flowで異常終了となる(※)。
(※)スタックの上限値による。上記例はスタック容量を1MByteとした場合の例。
(ex-2)の方は (foo(n-1)) のように関数呼び出しを括弧で括っており、
呼び出した後の戻り値を1つに調整するという処理が入るため、
末尾呼び出しとならず最適化が行われない。
0 件のコメント:
コメントを投稿