为什么堆栈跟踪会跳过一个显然必须被调用的函数才能达到以下函数?

时间:2013-07-11 02:14:32

标签: c++ debugging callstack

给定这样的设置,调用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()

DoInarBarStuff()的唯一引用是在DoBarStuff()中。 DoInternalBarStuff()在它的第一行断言:

assert(false);

这就是从中获取堆栈跟踪的位置。

2 个答案:

答案 0 :(得分:4)

对Bar :: DoBarInternalStuff的调用是否是Bar :: DoBarStuff中的最后一个语句?如果是这样,当调用Bar :: DoBarInternalStuff时,编译器很可能用Bar :: DoBarInternalStuff替换Bar :: DoBarStuff的堆栈帧。

这种tail call优化在C / C ++编译器中相当普遍。当递归函数可以被安排使得递归调用是函数中的最后一次调用时,它减少了所需的堆栈深度。

答案 1 :(得分:0)

事实证明,编译器会在某些优化级别进行自动内联。每天学习新事物。 :)

Does GCC inline C++ functions without the 'inline' keyword?

(感谢有用的评论向我展示了这一点。)