C是否需要堆栈和堆才能运行?

时间:2018-07-29 06:03:43

标签: c stack heap

人们谈论什么是栈和堆以及它们之间的区别。但是我很好奇,如果CPU不支持堆栈和堆结构,那么C可以在没有堆栈和堆的情况下正常运行吗?

3 个答案:

答案 0 :(得分:8)

不,不是。让我们先覆盖一下堆,很简单。

不提供任何种类的堆的实现只需要在尝试调用NULL(或任何其他内存分配函数)时返回malloc。根据标准,这是完全可以接受的行为。


就堆栈而言,它也不需要提供一个。 ISO C11完全零次提到“堆栈”一词。

实现 需要做的只是简单地为标准中指定的所有内容提供一个正确的“虚拟机”。当然,没有堆栈将非常困难,但并非没有可能。在极端情况下,没有什么可以说不能简单地递归地内联每个函数调用。那会使用大量的代码和特定于函数的数据空间,但这当然是可行的。

但是,可能是可以说服我迁移到另一种架构的东西,该架构具有 堆栈(就此而言,还有堆)。


已经说过,即使架构既不提供堆也没有提供堆栈,这两者都可以在基本内存I / O操作中构建。实际上,我少年时代最早使用的计算机之一就是RCA 1802 CPU,它没有专用的堆栈。它甚至没有callret指令。

然而,使用SCRT(标准调用和返回技术),它可以很好地处理子例程和堆栈(对于“ well”一词的定义)。有关这个美丽事物(或怪异的事物,取决于您的观点)以及其他一些不寻常的体系结构的更多详细信息,请参见here


IBM Z(又称System z,zSeries,无论他们本周称其为什么)实际上都有一个堆(各种各样,可以从OS分配内存),但是没有堆栈。它实际上通过使用此堆内存以及某些寄存器(类似于以上链接中引用的RCA芯片)来实现链接列表堆栈,这意味着函数序言使用STORAGE OBTAIN分配本地函数存储器,而Epilog释放它与STORAGE RELEASE

无需赘言,每个功能的序言和结尾都添加了很多额外的代码。

答案 1 :(得分:5)

C11标准(请参见n1570都不需要堆栈和堆,如其他答案所述。但是,实际上,两者都是有用的。

关于call stack,这很常见,但可能会“避免”:

  • 某些optimizing compilers可能足够聪明(特别是在整个程序优化或链接时优化中),可以检测到整个程序不需要任何程序的情况(简单的这种情况是一个没有函数指针且没有递归的完整程序:在这种情况下,每个“调用帧”都可以在编译时静态分配)。而且许多优化的编译器都是inlining的一些调用(有效地消除了这些调用的调用堆栈的需要),即使对于未标记为inline的函数也是如此。

  • 当今许多处理器(x86x86-64AVRSPARCColdFire,即mc68K ...)硬件调用堆栈(例如,一些“ stack pointerregister,已知为函数调用)。在那些没有这样的硬件堆栈指针的主机上(例如IBM Z series大型机,PowerPCMIPSRISC-V或也许ARM),{ {3}}(或calling convention)可能通常专用于某些寄存器,以充当堆栈指针的角色。 BTW,C甚至可以在理论上为ABI(没有任何寄存器或堆栈指针)实现。

  • 可以想象一个编译器使用random-access machines来避免调用栈(实际上是在某个或某些堆中“分配”一些“调用帧”,也许借助某些{{ 3}})。 Appel的旧书continuation-passing style详细解释了这个想法。我不能指定任何C编译器来执行此操作,但是标准允许这种方法。而且,如果您将某些编译器从C编码为SML(或某些Lisp),则可能会有这样的编译器。

关于C堆,malloc函数可能总是失败,并且仍然符合标准。 garbage collector,但最快。另外,C标准允许独立的实现完全没有任何malloc

如果您寻求C几乎需要的功能,我将研究二进制表示形式。我倾向于认为,为十进制计算机(如旧的Compiling with Continuations)或三元计算机(如I claim that such a malloc is useless)实现C11编译器是非常不切实际的(但原则上是可行的,因为您可以“ IBM 1620”是三进制或十进制的二进制计算机;全部为Setun。但是,您只会在博物馆中找到这样的旧计算机(1950年代末期,1960年代初),它们在C发明之前就消失了。

顺便说一句,在emulateTuring-complete(和ALGOL)实现中存在调用堆栈和堆,这比C早了几十年。

答案 2 :(得分:2)

C语言需要(如chqrlie所指出的)某种机制来实现自动存储并跟踪函数调用返回点。实际上,这总是一个堆栈。但这不需要堆。

仅当使用malloc之类的库函数时才使用堆;不是靠C语言本身。实际上,堆没有任何魔术-您可以用纯C语言编写mallocfree。它只有一大块static内存,并且有一种算法可以从该块中分配空间

您问“如果CPU不支持堆栈和堆结构”,该怎么办? 好吧,堆栈和堆只是由内存和指针构建的。我认为您不会找到任何可以视为不具备此功能的“ CPU”的处理器的示例。