簡體   English   中英

為什么不能將注冊變量設為全局變量?

[英]Why cant register variables be made global?

在從站點讀取時,您無法創建類型為 register 的全局變量。為什么會這樣? 來源: http : //publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=/com.ibm.xlcpp8l.doc/language/ref/regdef.htm

理論上講,您可以將處理器寄存器分配給全局范圍變量——該寄存器只需在程序的整個生命周期內保持分配給該變量即可。

然而,C 編譯器通常不會在編譯階段看到整個程序——C 標准的編寫是為了每個翻譯單元(大致對應於每個.c文件)可以獨立於其他編譯單元(使用編譯對象后來鏈接到一個程序)。 這就是為什么不允許全局范圍寄存器變量的原因 - 當編譯器編譯bc ,它無法知道有一個全局變量分配給ac的寄存器(因此bc函數必須保留該值登記)。

實際上,GCC 允許這樣做。 以以下形式在全局范圍內聲明:

register int foo asm ("r12");

為全局“foo”分配寄存器“r12”(在 x86_64 上)。 這有許多限制,相應的手冊頁可能是所有麻煩的全局寄存器變量的最佳參考:

因為那會毫無意義。 應用程序運行時始終存在全局變量。 這么長時間肯定沒有免費的處理器寄存器;)

最初,寄存器變量旨在存儲在處理器寄存器中,但全局變量必須存儲在數據或 BSS 部分中才能從每個函數訪問。 今天,編譯器並不嚴格解釋register存儲類,因此它主要是出於兼容性原因。

register關鍵字的含義與其名稱似乎表示的含義不同,現在它與處理環境的寄存器沒有太大關系。 (雖然它可能曾經被選擇為此。)限制使用用register聲明的變量的唯一文本是 this

一元 & 運算符的操作數應為函數指示符、[] 或一元 * 運算符的結果,或指定不是位字段且未使用寄存器存儲類說明符聲明的對象的左值

因此,它對自動變量(您在函數中聲明的變量)實施了限制,因此獲取此類變量的地址是錯誤的。 然后的想法是編譯器可以以任何喜歡的方式表示這個變量,作為寄存器或作為立即匯編程序值等。作為程序員的你保證你不會獲取它的地址。 通常這對全局變量沒有多大意義(無論如何,它們有一個地址)。

總結一下:

  • 不,不會忽略register關鍵字。
  • 是的,如果你想符合標准,它只能用於堆棧變量

寄存器字在 C/C++ 中用於請求編譯器使用處理器寄存器,如變量。 寄存器是 CPU 使用的一種變量,訪問速度非常快,因為它不位於內存 (RAM) 中。 寄存器的使用受體系結構和寄存器本身大小的限制(這意味着有些可能就像內存指針,其他加載特殊調試值等等)。

C/C++ 使用的調用約定不使用通用寄存器(80x86 Arch 中的 EAX、EBX 等)來保存參數(但返回值存儲在 EAX 中),因此您可以聲明類似寄存器的 var 使代碼更快.

如果您要求使其成為全球性的,則您要求為所有代碼和所有來源保留注冊。 這是不可能的,所以編譯器會給你一個錯誤,或者只是讓它成為存儲在內存中的普通變量。

一些編譯器提供了一種將寄存器永久地專用於變量的方法。 然而, register 關鍵字是不夠的。 編譯器決定在寄存器中為例程分配局部變量通常不需要與其他源模塊中的任何內容協調(雖然一些開發系統在例程之間進行寄存器優化,但更常見的是簡單地定義調用約定,以便所有例程允許自由更改某些寄存器(因此,如果在函數調用后需要它們,則調用者負責保存內容)但不得更改其他寄存器(因此,如果需要寄存器,則調用例程負責保存和恢復內容)函數)因此,鏈接器不需要關心寄存器的使用。

這種方法對局部寄存器變量很好,但對全局變量沒用。 為了使全局寄存器變量有用,程序員通常必須告訴編譯器哪個寄存器用於哪個變量,並確保在編譯所有模塊時編譯器知道這些保留——即使那些不使用否則注冊。 這在嵌入式系統中很有用,尤其是對於中斷使用的變量,但系統中允許的此類變量通常非常有限(例如 2 個左右)。

那么我們現在都同意了嗎? 我們是否都看到將全局變量設為寄存器變量是一個非常非常糟糕的主意? 如果最初的 C 定義沒有禁止它,那可能是因為沒有人認為有人會真正以這種方式實現它——尤其是在 CISC 時代,他們不應該這樣做。

此外:現代優化編譯器在決定何時將變量保存在寄存器中比人類做得更好。 如果你做不到,那么你真的,真的需要一個更好的編譯器。

因為它們在寄存器中。 這在術語上是矛盾的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM