簡體   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