簡體   English   中英

在c ++中存儲文字常量

[英]Storage of literal constants in c++

我想知道文字常量實際存儲在內存中的哪個位置?

例:

int i = 5;
char* data = char* &("abcdefgh");

idata的存儲部分取決於它們的聲明位置。 但是在將數據實際復制到變量之前,編譯器是否存儲了5"abcdefgh"

在這里,我可以獲得存儲它的"abcdefgh"的地址,但為什么我不能得到5的地址?

5這樣的整數文字可以是機器指令的一部分。 例如:

 LD A, 5

將值5加載到處理器寄存器A中用於某種虛構架構,並且因為5實際上是指令的一部分,所以它沒有地址。 很少(如果有的話)架構能夠在機器指令中內聯創建字符串文字,因此這些架構必須實際存儲在內存中的其他地方並通過指針訪問。 C ++標准沒有規定“其他地方”的確切位置。

在語言層面上 ,字符串文字和數字文字是不同的野獸。

C和C ++標准基本上指定字符串文字被視為“好像”您定義了具有適當大小和內容的常量字符數組,然后使用其名稱代替文字。 IOW,當你寫的時候

const char *foo = "hello";

就像你寫的一樣

// in global scope
const hello_literal[6] = {'h', 'e', 'l', 'l', 'o', '\0'};

...
const char *foo = hello_literal;

(有一些向后兼容的異常允許你甚至編寫char *foo = "hello";沒有const ,但是這已被棄用,並且無論如何都試圖通過這樣的指針寫入未定義的行為)

所以,鑒於這種等價,你可以擁有字符串文字的地址是正常的。 整數文字OTOH是rvalues ,標准規定你不能使用任何地址 - 你可以粗略地認為它們是標准期望在傳統意義上沒有后備存儲器位置的值。


現在,這種區別實際上源於這樣一個事實: 在機器級別它們通常以不同的方式實現。

字符串文字通常作為數據存儲在內存中的某個位置,通常位於只讀數據部分中,該部分直接從可執行文件映射到內存中。 當編譯器需要它的地址時,它很容易被強制,因為它是已經在內存中的數據內容,因此它確實有一個地址。

相反,當你做某事時

int a = 5;

5實際上沒有像上面的"hello world"數組那樣的單獨內存位置,但它通常作為直接值嵌入到機器代碼中。

有一個指向它的指針是相當復雜的,因為它將是一個指向指令中途的指針,並且通常以不同於您可以指向的常規int變量的預期格式指向數據 - 認為x86在哪里對於較小的數字,你使用更緊湊的編碼,或PowerPC / ARM和其他RISC架構,其中一些值是由隱式桶形移位器操縱的立即構建的,你甚至不能為某些值提供立即 - 你必須用幾個指令組成它們或哈佛架構,其中數據和代碼存在於不同的地址空間中。

因此,您不能獲取數字文字的地址(以及數字表達式評估結果和許多其他臨時內容); 如果你想擁有一個數字的地址,你必須先將它分配給一個變量(它可以提供一個內存存儲),然后詢問它的地址。

雖然C和C ++標准沒有規定文字的存儲位置,但通常的做法是將它們存儲在兩個地方之一:代碼(參見@NeilButterworth答案)或“常量”段。

常見的可執行文件具有代碼部分和數據部分。 數據段可以分成只讀,未初始化的讀/寫和初始化的讀寫。 通常,文字放在可執行文件的只讀部分。

某些工具也可能將文字放入單獨的數據文件中。 該數據文件可用於將數據編程到只讀存儲器設備(ROM,PROM,Flash等)中。

總之,文字的位置取決於實現。 C和C ++標准規定寫入文字位置是未定義的行為。 使用字符文字的首選做法是將變量聲明為const以便編譯器在寫入文字時生成警告或錯誤。

暫無
暫無

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

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