繁体   English   中英

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

[英]Are there stackless or heapless implementation of C++?

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

我们不会像汇编程序员那样看核心。 我们对裸机程序员的模型感到满意,只要存在所需的基础知识。 堆栈不是其中之一:我们最近遇到了几个无堆栈核心,并且没有为它们开发C编译器的问题。

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

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

飞思卡尔RS08是一款更传统的无堆叠MCU。 在“减少”HC08 / HCS08内核的过程中,飞思卡尔删除了CPU堆栈。 我们咨询了RS08的架构,我们从未觉得需要坚持使用硬件堆栈。

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

然后是“几乎无堆叠”。 Microchip PIC从未进行数据堆叠,只有8个条目(或增强型14位内核中的16个条目)的回调堆栈。 没有人怀疑C可用于PIC。

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

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

http://www.bytecraft.com/Stack_controversy

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM