C++ 中的调用堆栈是否先入/先出?

Does a call stack grow first in / first out in C++?

Each time we call the function, the stack of activation records (usually just called the stack) grows with one record. Conversely, when the function returns, its record is no longer used and so on. The stack (also called the call stack) is a data structure that grows and shrinks at one end according to the rule first in and first out.

最后一行是否正确?我在 Bjarne Stroustrup 的《使用 C++ 编程原则和实践》一书中读到了它。

这是一个错误。根据定义,堆栈是后进先出 (LIFO)。先进先出 (FIFO) 数据结构将是队列,而不是堆栈。

让我向您展示调用堆栈的工作原理:假设您有一个程序,其中包含一些函数和子函数,例如 f1()f1.1()f1.2()f1.1.1()f1.2.1()f1.2.2(),并且您有以下代码片段:

int f1(){
  if (<condition>){ // B1
    return f1.1();
    } else {
    return f1.2();
  }
}

int f1.1(){
  int temp = -1; // B2
  return f1.1.1();
}

int f1.2(){
  if <other_condition>{
    return f1.2.1(); // B3
  } else {
    return f1.2.2();
  }
}

int f1.1.1(){
  int temp = 1001001;
  return temp;
}

int f1.2.1(){
  int temp = 1002001;
  return temp;
}

int f1.2.2(){
  int temp = 1002002; // B4
  return temp;
}

B1-B4 表示您在该行放置了一个断点,并且执行的方式是命中这些断点。让我们看看调用堆栈如何看待这些时刻:

B1:调用堆栈:

f1()

B2:调用堆栈:

f1.1()
f1()

B3:调用堆栈:

f1.2() // at the moment of the breakpoint, f1.2.1() not yet executed.
f1()

B4:调用堆栈:

f1.2.2()
f1.2()
f1()

调用栈从下往上填充:首先添加f1()(该函数正在执行),当子函数(f1.1()f1.2())被执行时,即一个被添加到调用堆栈的顶部。一旦执行完成,它就会被删除。