2

インライン関数は、gcc が asm コードを生成するフェーズでそのコードに置き換えられます。

再帰関数にインラインを使用した場合の動作はどうなりますか

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

gcc -S再帰関数にinline接頭辞がある場合と再帰関数に接頭辞がない場合のasmコードを生成するinlineと、両方の場合のasmコードが同じであることがわかりました。

それについて何か説明はありますか?

4

4 に答える 4

6

inlineこれは、コンパイラが受け入れる場合と受け入れない場合があるコンパイラへの提案にすぎないことに注意してください。あなたの提案に固執することは、コンパイラーを拘束するものではありません。インテリジェントなコンパイラは、提案がなくても可能であれば関数をインライン化します。通常、再帰関数の場合、コンパイラは特定の深さまで行います。

コンパイラが機能しないのはなぜinlineですか?

再帰関数を使用すると、コンパイラは通常、末尾呼び出しの最適化を実行する機会を探します。あなたの関数は末尾呼び出し recursive ではありません

于 2013-01-21T15:20:30.050 に答える
4

はい:inline関数をインライン化する必要があることをコンパイラに実際に通知しません。必要な唯一の効果は、関数が複数のオブジェクト ファイルで定義されている可能性があることをリンカーに伝えることです。( がないinlineと、リンク時エラーになります。)

これにより、関数定義を複数の翻訳単位に含めることができるため、コンパイラは、リンカー エラーを生成せずに関数をインライン化するオプションを使用できます。最新のコンパイラは、関数をインライン化するかどうかを決定する際に、キーワードの存在を考慮する場合と考慮しない場合があります。inline

于 2013-01-21T15:21:31.747 に答える
0

関数へのポインターが必要な場合に備えて、すべてのインライン関数をコンパイルする必要があります。違いを確認するには、次のような場所で関数を使用する必要があります。

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


void main () {
    printf("%d\n", fact(2));
}
于 2013-01-21T15:25:25.490 に答える
0

他の人がすでに言っinlineたように、指示ではなく単なるヒントです。関数のインライン化に関する最終決定権はコンパイラにあります。何かを強制的にインライン化したい場合は、マクロを使用して実行できます。しかし、私が考える限り、再帰的なマクロを持つことはできないので、それは行き止まりです。

そうは言っても、関数のインライン化を強制できたとしても、(任意の最適化レベルで) コンパイラはいくつかの再帰関数を単純な while ループに展開できることを知っておく必要があります。そのため、最終的なアセンブリにパラドックスは見られません: 結果のループ単純にインライン化されます。

于 2013-01-21T15:26:56.190 に答える