2016-06-09 64 views
5

我知道引用不佔用任何內存,它將指向它所引用的同一內存位置。 用於如參考變量的存儲位置

int i=10; 
int &r = a; 

假設i指向的內存位置1000所以在這種情況下r也將指向內存位置1000 但在C++中當過我們聲明一個變量的意志得到存儲在存儲器中在某個位置。 在這種情況下,r指向某個位置,但它應該存儲在內存中某處作爲參考的內部表示僅使用const指針。 在此先感謝。

+2

如果r是一個變量,則r的地址是&r。這不是一個參考,C不是C++。所以如果r =&a,&r表示a的地址被存儲的地址。 – Tim

+0

'引用變量存儲在哪裏'這是未指定的。 –

回答

6

這是沒有具體說明,並有很好的理由。真正的答案是:它取決於參考。它可以表示爲普通指針,或者根本不存在。

如果您在使用自動存儲時間的函數,本地參考,像這樣的r

void foo() 
{ 
    int x[4] = {0, 1, 2, 3}; 
    int &r = x[1]; 
    // more code 
} 

那麼它可能不會佔用任何空間都沒有。編譯器將簡單地將r的所有用途作爲x[1]的別名,並直接訪問該int。請注意,這種別名式參考也可能來自函數內聯。另一方面,如果引用是「永久」的或對其他翻譯單元(如數據成員或全局變量)可見,則它必須佔用一些空間並存儲在某處。在這種情況下,它很可能會被表示爲一個指針,並且使用它的代碼將被編譯來取消引用該指針。

理論上,其他選項也是可能的(例如查找表),但我不認爲這些選項被任何現實世界的編譯器使用。

1

我知道,引用不採取任何內存

不完全是。參考文獻是否有存儲空間,沒有具體說明。它可能會或可能不會。在這個特殊的例子中,它不需要存儲,所以在典型的實現中,它不使用任何存儲。

這將指向其所引用

相同的內存位置這聽起來像一個同義反復或只是一個誤會,這取決於你的意思是「」什麼。 參考到物體或綁定到物體。您可以將其視爲變量名的別名。變量名稱也不使用任何內存。

在這種情況下,r爲指向某個位置,但它應該在某處存儲在內存中

它並不需要被存儲在內存中。請考慮下面的代碼:

int i=10; 
int &r = a; 
int j = r * 3; 

編譯器可以解釋r * 3i * 3,如果你已經在第一時間書面左右。被引用對象的位置在編譯時已知,因此不需要將該地址存儲在運行時的內存中。

但是,在其他情況下,可能需要存儲。例如:考慮具有外部鏈接的非內聯函數的引用參數。在編譯函數時不能知道引用的對象,因此必須在運行時將一些信息傳遞到內存中。

作爲參考使用const的內部表示指針只

這是不正確的。內部表示可能使用一個指針,或者可能使用其他的東西,或者它可能不需要使用任何東西。

所以,能夠簡明地回答

哪裏引用變量被存儲

這是不確定的。無處不在,或者某處。

0

標準說什麼:

這是不確定的引用是否需要存儲(3.7)。

(C++ 11,[dcl.ref]¶4)

這意味着,編譯器可以自由地在每個個案基礎是否需要任何存儲選擇。現在,讓人們說出他們想要的東西,但是引用歸結爲指針的語法糖(即使在編譯器級別,在所有主要的C++編譯器中,「引用」概念幾乎立即在前端之後消失)。因此,在一般情況下,它們可能需要它們在存儲器中的空間,就像指針一樣。但是,在像你這樣的情況下(本地引用),編譯器應該通過它們並根據需要優化它們。

但是請注意,這不是排他引用 - 即使通過指針,編譯器也能夠執行相同類型的優化(一旦代碼以SSA形式出現,即使引用不能被重新設置)。

此:

int glob; 

void direct() { 
    glob = 16; 
} 

void through_reference() { 
    int &a = glob; 
    a = 16; 
} 

void through_pointer() { 
    int *a = &glob; 
    *a = 16; 
} 

總是歸結爲對任何編譯器相同的代碼我試過gcc.godbolt.org - example

direct(): 
     mov  DWORD PTR glob[rip], 16 
     ret 
through_reference(): 
     mov  DWORD PTR glob[rip], 16 
     ret 
through_pointer(): 
     mov  DWORD PTR glob[rip], 16 
     ret 
glob: 
     .zero 4 

在另一方面,這種情況得到了在談論結構時更容易滑溜;在這裏,編譯器允許從結構的實際佈局中去除引用(如果它能夠重建它們實際指向的內容),而對於指針來說,情況可能會更復雜一點(它們的省略會破壞標準佈局類東東)。

實際上,我從來沒有在實際的編譯器中看到過這種優化。採取海灣合作委員會或MSVC或鏗鏘或任何,你會看到結構大小將出來相等even in the most trivial cases

0

作爲參考使用const的內部表示指針只

你是從哪裏聽來的?那是不正確的。

該標準沒有指定如何實現引用。

以下是過於簡化

最常見的是,編譯器在內部,它存儲所有它所需要的有關變量的信息的符號表。

讓我們以一個簡單的例子:

int a; 
a = 100; 

那麼編譯器能有這樣的事情(爲簡單起見,讓使a地址固定的已知地址)

| identifier | type | address | 
|------------|------|----------| 
| a   | int | 0xFF00A4 | 

然後,它可以轉化C++代碼變成這樣的東西:

mov 0xFF00A4, 100 

讓' S IN的搭配添加引用:

int a; 
a = 100; 
int& ra = 300; 

符號表中的編譯器有:

| identifier | type | address | 
|------------|------|----------| 
| a   | int | 0xFF00A4 | 
| ra   | int& | 0xFF00A4 | 

或者:

| identifier | type | address | alias | 
|------------|------|----------|-------| 
| a   | int | 0xFF00A4 | -  | 
| ra   | int& | -  | a  | 

,因此可以產生這樣的代碼:

mov 0xFF00A4, 100 
mov 0xFF00A4, 300 

當你在函數中有一個引用參數時,指針會在內部傳遞。

+0

這不是專用於參考;編譯器甚至可以在指針上執行這種優化,一旦所有東西都以SSA形式出現,就沒有什麼區別。 –