1. ホーム
  2. c++

[解決済み] なぜコードは積極的にテールコールの最適化を防ごうとするのだろうか?

2023-07-17 20:15:03

疑問点

質問のタイトルは少し奇妙かもしれませんが、私の知る限りでは、テールコールの最適化に対して話すことは全くありません。しかし、オープンソースプロジェクトを閲覧しているとき、私はすでに積極的にテールコールの最適化を行うからコンパイラを停止しようとするいくつかの関数、例えば、実装の CFRunLoopRef の実装のように、このような ハック . 例えば

static void __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__() __attribute__((noinline));
static void __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__(CFRunLoopObserverCallBack func, CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info) {
    if (func) {
        func(observer, activity, info);
    }
    getpid(); // thwart tail-call optimization
}

なぜこのようなことが重要だと思われるのか、また、私自身が 通常 の開発者がこのことを心に留めておく必要があるようなケースはありますか?例えば、テールコールの最適化で一般的な落とし穴があるのでしょうか?

どのように解決するには?

私が推測するところでは、以下のことを確実にするためです。 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ がスタックトレースに含まれるようにするためだと思います。これには __attribute__((no inline)) があり、この考えを裏付けています。

気づいたら、その関数はとにかく別の関数に移動して跳ねています。これはトランポリンの一種で、デバッグを助けるためにこのような冗長な名前がついているとしか思えません。これは、関数が他の場所から登録された関数ポインターを呼び出しているため、その関数がアクセス可能なデバッグ シンボルを持たない可能性があることを考えると、特に有用でしょう。

バックトレースから何が起こったかを見るのに役立つように、本当にそこにあるように見えます。 これは Mac OS X のコア コードであり、クラッシュ レポートおよびプロセス サンプル レポートにも表示されることを覚えておいてください。