[英]Why address-of operator ('&') can be used with objects that are declared with the register storage class specifier in C++?
在C編程語言中,我們不允許將address-of運算符(&)與使用寄存器存儲類說明符聲明的變量一起使用。
它給出了error: address of register variable 'var_name' requested
但是,如果我們制作一個c ++程序並執行相同的任務(即使用&
with寄存器存儲變量),它不會給我們任何錯誤。
例如。
#include <iostream>
using namespace std;
int main()
{
register int a;
int * ptr;
a = 5;
ptr = &a;
cout << ptr << endl;
return 0;
}
輸出: -
0x7ffcfed93624
那么這必須是C ++的一個額外功能,但問題在於C和C ++中寄存器類存儲的區別。
在C ++中故意刪除了取得地址的限制 - 它沒有任何好處,它使語言更復雜。 (例如,如果綁定對register
變量的引用會發生什么?)
register
關鍵字多年來沒有多大用處 - 編譯器非常擅長確定自己放入寄存器的內容。 實際上,在C ++中,該關鍵字目前已被棄用,最終將被刪除。
register
存儲類最初向編譯器暗示如此頻繁地使用變量如此合格,以至於將其值保留在存儲器中將是性能缺陷。 絕大多數 CPU架構(可能不是SPARC?甚至不確定是否存在反例)如果沒有先將一個或兩個從內存加載到其寄存器中,就無法在兩個變量之間執行任何操作。 將變量從存儲器加載到寄存器中並在操作后將它們寫回存儲器所需的CPU周期比操作本身多出許多倍。 因此,如果頻繁使用變量,則可以通過為其預留寄存器而不打擾存儲器來實現性能增益。
但是,這樣做有各種各樣的要求。 每種CPU架構都有許多不同之處:
register
變量。 register
變量不適合寄存器的情況。 由於C旨在獨立於平台,因此標准無法強制執行這些限制。 換句話說,雖然對於只有4個機器寄存器的系統來說,編譯一個帶有20個register
變量的過程是不可能的,但是C程序本身不應該是“錯誤的”,因為沒有邏輯上的原因機器不能有20個寄存器。 因此, register
存儲類始終只是一個提示 ,如果特定目標平台不支持它,編譯器可以忽略它。
無法引用寄存器是不同的。 register
具體不在存儲器中保持更新,如果對存儲器進行了更改,則不保持當前狀態; 這就是存儲類的重點。 由於它們不打算在內存中具有保證的表示,因此它們在邏輯上不能在內存中具有對可能獲得指針的外部代碼有意義的地址。 寄存器沒有自己CPU的地址,並且它們幾乎從不具有任何協處理器可訪問的地址。 因此,任何獲取對register
的引用的嘗試總是錯誤的。 C標准可以輕松地執行這一規則。
然而,隨着計算的發展,一些趨勢的發展削弱了register
存儲類本身的目的:
實際上,編譯器現在非常善於將變量分配給寄存器,它們通常在優化方面比任何人都做得更好。 他們當然知道你最常使用哪些,而不告訴他們。 如果編譯器需要遵守手動register
提示,那么編譯器 (即不適用於標准或程序員)會產生這些優化會更復雜。 編譯器斷然忽略它們變得越來越普遍。 到C ++存在時,它已經過時了。 它包含在標准中以便向后兼容,以使C ++盡可能接近C的正確超集。編譯器遵守提示的要求以及因此強制執行提示可以遵守的條件的要求被削弱了因此。 今天,存儲類本身已被棄用。
因此,即使現在仍然如此(並且直到計算機甚至沒有寄存器)你無法邏輯地引用CPU寄存器, register
存儲類將被尊重的期望已經過時了標准要求編譯器要求您在使用它時合乎邏輯是不合理的。
引用的寄存器將是寄存器本身。 如果調用函數將ESI作為引用參數傳遞,則被調用函數將使用ESI作為參數。 正如Alan Stokes所指出的,問題是如果另一個函數也調用相同的函數,但這次使用EDI作為相同的引用參數。
為了使其工作,需要創建兩個重載的被調用函數實例,一個以ESI作為參數,一個以EDI作為參數。 我不知道是否有任何實際的C ++編譯器實際上實際上實現了這樣的優化,但這就是如何做到的。
通過引用注冊的一個示例是std :: swap()被優化的方式(兩個參數都是引用),這通常最終成為內聯代碼。 有時沒有交換發生:例如,std :: swap(a,b),沒有發生交換,而是在后面的代碼中交換a和b的意義(引用對b和副的引用是什么反之亦然)。
否則,引用參數將強制變量位於內存而不是寄存器中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.