是否有无堆栈或无堆的C++实现?

Mes*_*sop 19 c++ heap standards stack stackless

C++标准没有提到有关堆栈或堆的任何内容,它们是特定于实现的,这是事实.

即使它们不是C++标准的一部分,我们最终仍然使用它们,以至于它们就像语言本身的一部分一样,必须考虑到内存或性能目的.

因此我的问题是C++的实现不使用堆栈和堆?

Jer*_*fin 11

其他人已经给出了关于堆的好答案,所以我将单独留下.

一些实现(例如,在IBM大型机上)不使用堆栈,因为大多数人会想到它,原因很简单,硬件不支持它.相反,当您调用函数时,会从堆(它们的版本)中分配激活记录(即本地,参数和返回地址的空间).这些激活记录内置在链表中.

从纯粹抽象的角度来看,这肯定是一个堆栈 - 它支持后进先出语义,就像任何其他堆栈一样.你必须非常抽象地看它,把它称为堆栈.如果你向人们展示链接在一起的内存块图表,我认为大多数程序员都会将其描述为链表是安全的.如果你推动它们,我认为大多数人会判断它是"是的,你可以像堆栈一样使用它,但它仍然是一个链表."

  • 看起来与 MIPS 类似。在 MIPS 中,调用指令只是“jal”(跳转和链接)。也没有堆栈指针,您只需使用任何寄存器来指向内存区域并将其称为堆栈。推/弹出操作将手动处理 (2认同)

Joh*_*ing 5

C++标准没有提到有关堆栈或堆的任何内容

实际上它确实 - 只是没有用那些语言,也没有说明如何实现堆栈和堆.

在C++ 03中有三种变量:

  1. 具有静态存储持续时间(3.7.1)的那些.这些是程序期间的"范围内".
  2. 具有自动存储持续时间(3.7.2)的那些.这些仅在声明它们的上下文中.一旦它们超出范围,变量就会被销毁和解除分配.
  3. 具有动态存储持续时间(3.7.3)的那些.这些是用new表达式创建的,并用a来销毁delete.对象本身是无范围的,因为它们的生命周期不受它们被new编辑的上下文的约束.当然,对这些对象的即时指针是作用域.指针具有自动或很少(通常是错误的)静态存储持续时间.

"Stack"和"Heap"实际上就是后来的第二种两种类型的对象.它们是与平台相关的实现细节,可实现语言要求.

所以,从技术上讲,你是对的.标准没有说明堆和堆栈.但它确实说了不少关于存储时间的不同口味需要一些在真实的平台类型的实现.在大多数现代PC类型硬件上,这是作为堆和堆栈实现的.可以在不使用堆或堆栈的情况下在平台上实现不同类型的存储持续时间吗?一切皆有可能 - 我想它可以.但无论实现最终如何,它可能具有与两者中的至少一个类似的特征.

除此之外,还需要考虑标准要求自动和动态存储持续时间.任何不符合这两个要求的语言实现都不是C++.它可能很接近,但它实际上不是C++.

  • "实际上确实如此"接着是关于它如何不做的几个段落. (6认同)
  • @LightnessRacesinOrbit 这就是约翰·迪布林(John Dibling)通过“不是用那些话,并且没有指定如何实现堆栈和堆”来澄清的意思。栈和堆是抽象概念,ESP寄存器和malloc函数在这里并不重要。 (2认同)

Pet*_*ham 5

对于小型编程环境,例如基于 8K Atmel 微处理器的arduino 平台(现在有 32K 或更多),没有实现堆,并且库没有定义新的运算符。所有对象都是静态创建的或在堆栈上创建的。您失去了标准库的优势,但能够使用面向对象的语言对非常小的平台进行编程 - 例如,创建类来表示配置为特定输出模式或串行端口的引脚,创建该类的对象给它引脚号,然后调用该对象上的函数,而不必将引脚号传递给您的例程。

如果您new在 arduino 上使用,您的程序会编译但不会链接 - 编译器是针对 avr 指令集的 g++,真正的 C++ 编译器也是如此。如果您选择提供自己的实现,则可以这样做,但在大多数情况下,在如此小的占地面积上提供实现的成本是不值得的。

  • (operator new 是在 1.0 版中添加到 arduino 中的,所以这个例子现在已经过时了) (3认同)
  • 学究气:如果没有 new 运算符,它就不是 C++。 (2认同)
  • @JohnDibling 很多 g++ 用户会认为 g++ 是一个 C++ 编译器。 (2认同)