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

时间:2012-06-05 16:12:26

标签: c++ stack standards heap stackless

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

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

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

7 个答案:

答案 0 :(得分:11)

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

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

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

答案 1 :(得分:5)

  

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

它实际上确实 - 只是没有用那些词,并没有具体说明堆栈和&堆已经实施。

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

  1. 静态存储持续时间(3.7.1)的用户。这些都是程序期间的“范围内”。
  2. 自动存储持续时间(3.7.2)的用户。这些仅在声明它们的上下文中。一旦它们超出范围,变量就会被破坏。解除分配。
  3. 动态存储时间(3.7.3)的用户。这些是使用new表达式创建的,并使用delete销毁。对象本身是无范围的,因为它们的生命周期不受它们new编辑的上下文的约束。当然,对这些对象的即时指针是作用域。指针是自动的,很少(通常是错误的)静态存储持续时间。
  4. “Stack”和“Heap”实际上就是后来的第二种两种类型的对象。它们是与平台相关的实现细节,可以实现语言要求。

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

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

答案 2 :(得分:2)

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

如果你在arduino上使用new,你的程序编译但不链接 - 编译器是g ++,目标是avr指令集,所以是一个真正的C ++编译器。如果您选择提供自己的实现,则可以这样做,但在大多数情况下,在如此小的占用空间内提供实现的成本并不值得。

答案 3 :(得分:1)

这基本上是回应TA先生的答案(+1 BTW)。堆栈和堆是抽象的概念。

newdelete运算符(以及mallocfree函数)实际上只是一个称为堆的抽象接口。因此,当您要求C ++实现“无堆”时,您实际上是要求实现不允许您使用这些接口。我认为没有什么能阻止实现总是使这些接口失效。

调用函数并在调用返回后恢复当前执行(并且可选地检索返回值)是堆栈抽象的接口。当您要求C ++实现为“无堆栈”时,您要求C ++实现禁止程序执行这些操作。我想不出编译器强加这种情况的一致方式。该语言规定允许源代码定义函数,并定义调用函数的代码。

所以我的回答是可能的:“无堆叠”否,“无堆”是的。

答案 4 :(得分:0)

由于C ++定义了诸如函数和new运算符之类的结构,因此不能实现无堆栈和无堆实现。调用一个函数需要一个堆栈,而一个实例的“新”需要一个堆。这些实现方式在不同平台之间可能有所不同,但这个想法是一样的。总是需要一个用于实例对象的存储区域,以及另一个用于跟踪执行点和调用层次结构的存储区域。

由于x86(和x64)具有便利的设施(即ESP寄存器),编译器使用它。其他平台可能不同,但最终结果在逻辑上是等效的。

答案 5 :(得分:0)

我敢说没有这样的C ++实现,只是因为堆栈和堆是非常有用的抽象,基本上所有市场上的处理器都提供了一些硬件支持,使它们非常高效。

由于C ++旨在提高效率,C ++实现将利用它们。另外,C ++程序通常不在真空中运行。它们必须集成到平台生态系统中,平台生态系统由平台Application Binary Interface定义。 ABI - 出于同样的原因 - 定义了C ++实现需要遵守的堆栈和其他内存结构。

但是,我们假设您的C ++程序针对的是一个简单,小型,资源受限的嵌入式平台,其中包含一个奇特的微控制器,没有操作系统(您的应用程序将是操作系统!),并且没有线程或进程。

首先,平台可能根本不提供动态内存。您需要使用链接时定义的静态内存池,并开发自己的内存分配管理器(new)。 C ++允许它,并且在某些环境中确实使用它。

此外,CPU可能使堆栈抽象不那么有用,因此不值得实现。例如,像SPARC这样的CPU定义了一个滑动register window mechanism - 与大量寄存器相结合 - 使得堆栈对函数调用的效率不高(如果你看一下,堆栈已经在HW中完成了!)

长话短说,所有C ++实现都使用堆栈,大多数使用堆,但原因与平台属性密切相关。

答案 6 :(得分:0)

是的,主要是像飞思卡尔和PIC这样的MCU

  

2。现在正在使用无堆栈处理器。

     

我们不会像汇编程序员那样看核心。我们很开心   只要有要求,就可以使用裸机程序员的模型   基本面存在。堆栈不是其中之一:我们遇到过   最近几个无堆栈核心,并没有发展的问题   C编译器。

     

eTPU是一款24位增强型时间处理单元,用于汽车领域   和通用航空发动机控制和过程控制。 eTPU可能是   一个协处理器,但它有一个完整的指令集和一个完整的CPU   核心,它是无堆叠的。它是一个中等容量的处理器:机会是   你今晚开车或飞回家,在C上无人驾驶   处理器。

     

我们有一个基于C99和ISO / IEC 18037的eTPU的C编译器。   我们在这个处理器上运行标准的C测试套件。

     

飞思卡尔RS08是一款更传统的无堆叠MCU。在里面   "减少"在HC08 / HCS08核心,飞思卡尔取消了CPU   堆。我们咨询了RS08的架构,我们从未感受过   需要坚持硬件堆栈。

     

提到我们咨询的另一个协处理器,即飞思卡尔XGATE   有一个非常友好的ISA和程序员的模型,但它没有   叠加。

     

然后就是#34;几乎无堆叠"。 Microchip PIC从未有过数据   堆叠,只有8个入口(或增强型14位中的16个入口)   核心)call-return stack。没有人怀疑C可用于PIC。

     

这些部分,尤其是eTPU,被设计为编译器   友好并鼓励机器生成的代码。

     

还有其他非堆栈处理器,有些是最近创建的,   跨越一系列应用程序并享受自己的C语言   编译器。有大量中等容量的无堆叠部件。性能   通常是零件没有堆叠的主要原因。

     

http://www.bytecraft.com/Stack_controversy