2010-10-06 36 views
2

根據@Patatoswatter的建議,我創建了一個新的討論。參考表達式的評估

參考是從@Potatoswatter

this response

考慮的代碼片段,

int i = 3, &j = i; 
j = ++ i; 

即我謀上清晰的註釋,是這樣的。 (這似乎是在我的未測序評價a.k.a序列點的理解的重要缺失的那一塊):

@Chubsdad:儘管這是一個別名, 其glvalue評價不 需要我的glvalue評價。 一般而言,評估 參考不需要原始對象在手。有 沒理由它應該是UB,所以它使得 感覺應該有一個簡單的漏洞 或者轉化爲不是 的UB代碼。

參考不告訴 編譯器去看看引用 變量,並得到其左值,因爲它 可能不知道什麼是變量引用 。編譯器計算引用的左值,並且左值標識對象。如果您要 想進一步辯論,請 開個新問題。

在這個問題的任何可能缺乏明確的是「不確定的行爲」我通過努力理解「未測序的評價」,「序列點」會的一部分等C++ 0x中。

+0

只是爲了修補第一個陳述,「手頭上」的意思是「靜態確定」。通過「轉換爲不是UB的代碼」,我的意思是將由於對lvalue對象的副作用而產生的UB代碼進行處理,其隨後不被評估爲rvalues,例如'i = ++ i',並將引用變量'j'在這裏)複製這樣的左值,所以它們的評估不會受名義上的副作用的影響。 – Potatoswatter 2010-10-06 13:18:27

回答

2

想象一下以下

int &i = *new int; 

如果說i是另一名的別名 - 什麼名字?一個引用或者引用一個對象或者函數。當你說「glvalue」時,你引用特定表達式的屬性,而不是指對象的屬性。現在

int i = 0; 
int &ri = i; 

i是一個左值表達和ri是一個左值表達式太(二者句法類別id-expression的)。他們名稱(通過名稱查找找到)一個參考和一個int變量。

如果您現在確定ri大小寫的對象標識,則需要採用該引用並使該表達式引用其初始化的對象。這被稱爲左值評估,因爲您確定了左值(即參考值)的屬性。

您需要爲i的情況做同樣的事情。即你找出左值表達式i所指的是什麼對象。因此,ri的glvalue評估與i的glvalue評估不同,儘管它們都產生相同的結果。

Rvalue評估意味着取左值並將左值應用於右值轉換。換句話說,要讀取一個值。

+0

那麼這句話是否仍然正確(如在OP中)? (引用並沒有告訴編譯器去查看引用的變量並得到它的左值,因爲它可能不知道引用了什麼變量) – Chubsdad 2010-10-07 05:08:07

+0

@Chubsdad「變量」表示「命名對象」。正如我上面顯示的那樣,引用可以引用未命名的對象。我認爲他的意思是說,引用不像是「鏈接到編譯器的符號表」,而更像是「引用地址」中的指針。 – 2010-10-07 19:57:42

1

從概念上講,C++中的引用是某個對象的別名或替代名稱。當涉及到引用時,這個概念應該引導你理解語言規則。

基本上有實現C++的引用的方法有兩種:

  1. 如在編譯器的符號表的註釋。這是唯一可能的,如果引用只能綁定到一個對象,但它也保持最接近引用的概念。國際海事組織,大多數編譯器在可能的情況下使用這種技術,例如這裏介紹的例子。
  2. 作爲一個指針,在每個操作中自動取消引用。這是後退解決方案,因爲它與參考概念不匹配,但它確實使實現參考類型函數參數更容易,而不必嚴重更改ABI。

在所提出的示例中,存在一個從未方式可以有參考j未綁定到對象i,所以編譯器將最有可能使用實施參考的符號表註釋方法。這意味着,在聲明ij後,它們可以在代碼中互換使用,而不會對生成的代碼或定義行爲的問題產生任何影響。