人们谈论什么是栈和堆以及它们之间的区别。但是我很好奇,如果CPU不支持堆栈和堆结构,那么C可以在没有堆栈和堆的情况下正常运行吗?
答案 0 :(得分:8)
不,不是。让我们先覆盖一下堆,很简单。
不提供任何种类的堆的实现只需要在尝试调用NULL
(或任何其他内存分配函数)时返回malloc
。根据标准,这是完全可以接受的行为。
就堆栈而言,它也不需要提供一个。 ISO C11完全零次提到“堆栈”一词。
实现 需要做的只是简单地为标准中指定的所有内容提供一个正确的“虚拟机”。当然,没有堆栈将非常困难,但并非没有可能。在极端情况下,没有什么可以说不能简单地递归地内联每个函数调用。那会使用大量的代码和特定于函数的数据空间,但这当然是可行的。
但是,可能是可以说服我迁移到另一种架构的东西,该架构具有 堆栈(就此而言,还有堆)。
已经说过,即使架构既不提供堆也没有提供堆栈,这两者都可以在基本内存I / O操作中构建。实际上,我少年时代最早使用的计算机之一就是RCA 1802 CPU,它没有专用的堆栈。它甚至没有call
或ret
指令。
然而,使用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
的函数也是如此。
当今许多处理器(x86或x86-64,AVR,SPARC,ColdFire,即mc68K ...)硬件调用堆栈(例如,一些“ stack pointer” register,已知为函数调用)。在那些没有这样的硬件堆栈指针的主机上(例如IBM Z series大型机,PowerPC,MIPS,RISC-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发明之前就消失了。
顺便说一句,在emulate和Turing-complete(和ALGOL)实现中存在调用堆栈和堆,这比C早了几十年。
答案 2 :(得分:2)
C语言需要(如chqrlie所指出的)某种机制来实现自动存储并跟踪函数调用返回点。实际上,这总是一个堆栈。但这不需要堆。
仅当使用malloc
之类的库函数时才使用堆;不是靠C语言本身。实际上,堆没有任何魔术-您可以用纯C语言编写malloc
和free
。它只有一大块static
内存,并且有一种算法可以从该块中分配空间
您问“如果CPU不支持堆栈和堆结构”,该怎么办? 好吧,堆栈和堆只是由内存和指针构建的。我认为您不会找到任何可以视为不具备此功能的“ CPU”的处理器的示例。