6

私がこのような単純な関数を持っているとしましょう:

int all_true(int* bools, int len) {
    if (len < 1) return TRUE;
    return *bools && all_true(bools+1, len-1);
}

この関数は、次のように、より明確な末尾再帰スタイルで書き直すことができます。

int all_true(int* bools, int len) {
    if (len < 1) return TRUE;
    if (!*bools) return FALSE;
    return all_true(bools+1, len-1);
}

論理的には、2つの間にゼロの違いがあります。または(適切に定義された)boolsのみが含まれていると仮定すると、それらはまったく同じことを行います。TRUEFALSE

私の質問は、コンパイラが末尾再帰呼び出しとして2番目を最適化するのに十分賢い場合、「&&」が短絡していることを考えると、同じ方法で最初を最適化することを期待するのは合理的ですか?明らかに、非短絡演算子が使用された場合、演算子が適用される前に両方の式が評価されるため、これは末尾再帰ではありませんが、短絡の場合については興味があります。

(Cコンパイラは通常、末尾再帰呼び出しを最適化しないというコメントが殺到する前に、これは、言語に関係なく、短絡演算子を使用した末尾再帰呼び出しの最適化に関する一般的な質問だと考えてください。これをScheme、Haskell、OCaml、F#、Python、またはCを理解していない場合は、これまでにないもので書き直してください。)

4

1 に答える 1

2

あなたの質問は本当に「コンパイラはどれくらい賢いのか」です。ただし、使用しているコンパイラについては説明しません。

最適化の前にソースコードを中間フローグラフに変換する架空の妥当なコンパイラを考えると、作成したコードの両方のフラグメントを同じ方法で表すことができます(&&演算子は入力に便利ですが、 &operator;したがって、架空のコンパイラーで1つのフェーズで拡張されても驚かないでしょう)。その仮定では、あなたの質問に対する答えは「はい」であると断言するのは合理的です。

ただし、実際にこれに依存する場合は、使用しているコンパイラを使用してテストする必要があります。

于 2011-12-15T06:47:37.647 に答える