1. ホーム
  2. c++

[解決済み] 再帰的な関数はインライン化できますか?

2022-05-05 23:47:48

質問

inline int factorial(int n)
{
    if(!n) return 1;
    else return n*factorial(n-1);
}

を読んでいるうちに これ このコードは、コンパイラによって正しく処理されないと、無限コンパイルにつながることがわかりました。

コンパイラは関数をインライン化するかどうか、どのように判断しているのですか?

どのように解決するのですか?

まず inline の指定は単なるヒントに過ぎません。 コンパイラは、関数中の inline 修飾子を使用します。 とはいえ、コンパイラが できる 無限ループを展開するのと同じように、再帰的な関数をインライン化することができます。 無限ループを展開するのと同じように、再帰関数をインライン化する場合、そのレベルに制限を設けるだけでよいのです。

最適化されたコンパイラは、このコードを回すかもしれない。

inline int factorial(int n)
{
    if (n <= 1)
    {
        return 1;
    }
    else
    {
        return n * factorial(n - 1);
    }
}

int f(int x)
{
    return factorial(x);
}

をこのコードに置き換えます。

int factorial(int n)
{
    if (n <= 1)
    {
        return 1;
    }
    else
    {
        return n * factorial(n - 1);
    }
}

int f(int x)
{
    if (x <= 1)
    {
        return 1;
    }
    else
    {
        int x2 = x - 1;
        if (x2 <= 1)
        {
            return x * 1;
        }
        else
        {
            int x3 = x2 - 1;
            if (x3 <= 1)
            {
                return x * x2 * 1;
            }
            else
            {
                return x * x2 * x3 * factorial(x3 - 1);
            }
        }
    }
}

この場合、基本的に関数を3回インライン化したことになります。 一部のコンパイラは する はこの最適化を行います。 MSVC++には、再帰的な関数に対して実行されるインライン化のレベルを調整する設定があったのを覚えています(最大20まで、確か)。