1

DoFooStuff() が呼び出されるこのようなセットアップを考えると:

class Foo {
public:
    void DoFooStuff(); // calls Bar::DoBarStuff()
}

class Bar {
public:
    void DoBarStuff(); // Calls Bar::DoInternalBarStuff()
protected:
    void DoInternalBarStuff();
}

私のスタック トレースがこれを正確に示すことができるのはなぜですか?:

Type                   Function
void                   Bar::DoInternalBarStuff()
void                   Foo::DoFooStuff()

DoInternalBarStuff() への唯一の参照は、DoBarStuff() 内にあります。DoInternalBarStuff() は、最初の行でアサートします。

assert(false);

そして、そこからスタック トレースが取得されます。

4

2 に答える 2

4

Bar::DoBarInternalStuff への呼び出しは、Bar::DoBarStuff の最後のステートメントですか? その場合、コンパイラは、Bar::DoBarInternalStuff が呼び出されたときに、Bar::DoBarStuff のスタック フレームを Bar::DoBarInternalStuff のスタック フレームに置き換えた可能性が最も高いです。

この種の末尾呼び出しの最適化は、C/C++ コンパイラではかなり一般的です。再帰呼び出しが関数の最後の呼び出しになるように再帰関数を配置できる場合に必要なスタックの深さを減らします。

于 2013-07-11T03:04:40.230 に答える