2016-09-06 81 views
6

我碰到麻煩等同於以下代碼:const引用的地址是否可以與引用對象的地址不同?

const auto &const_reference = some_object; 
assert(&const_reference == &some_object); 

當我與G編譯它++ -O3標誌,它不通過斷言。在沒有優化的情況下編譯時,會傳遞斷言。

據我所知,即使在我的項目中有UBs這種情況也不應該是可能的。

是否有任何情況下會出現此類參照行爲?

編輯: 鏈接到實際的代碼:https://github.com/Gray0Ed/ggp_thesis/blob/67606021020546b315ad63b7fd5c2203f3e0086f/rule_engine/aligner.cpp#L177 - 項目有點混亂,它不是真的準備公開顯示,但如果你好奇,隨時看看它。

編輯2: 由於RustyX指出的原始代碼與上面給出的「等價物」不同,請查看他的答案以查看詳細信息。

+5

由於兩個「爲const_reference」和「some_object」指的是同一個對象,平等必須始終堅持。這可能是未定義行爲的一個症狀,但是不可能猜測到哪裏。 (唯一的另一種可能性是它是一個編譯器錯誤,這不太可能。)首先發布一些實際的代碼,而不是「等價的」。 – molbdnilo

+0

什麼版本的gcc?這可能是一個編譯器錯誤,我的gcc認爲即使使用-O3也沒問題。 – Elijan9

+3

你是否超載'運營商&'? – Jarod42

回答

4

此代碼將始終工作:

const auto &const_reference = some_object; 
    assert(&const_reference == &some_object); 

不工作的實際代碼實際上是這樣的:

const auto &oc = ai->var_infos[var_id].occurences[0]; 
    assert(&oc == &ai->var_infos[var_id].occurences[0]); 

它不工作,因爲你重載operator[]

查看MyArrays.hpp:

T operator[](size_t i) const { 
    assert(size >= 0); 
    assert(i < size && i >= 0); 
    return items[i]; 
} 

每次調用時都會返回一個副本

這也許應該是:

const T& operator[](size_t i) const { 
    assert(size >= 0); 
    assert(i < size && i >= 0); 
    return items[i]; 
} 
+1

特別是,第一個'[]'做了一個副本,因爲'ai'是一個指向'const'的指針,然後第二個'[]'在一個非常量臨時副本上被調用,返回一個引用到所述副本中,導致一個巨大的混亂。 –

+0

哇,非常感謝你RustyX,當然你是對的,我已經給你部分錯誤的信息,你仍然設法解決這個問題。 。 – Gray0Ed

+0

@RustyX你知道爲什麼這個表達式'&ai-> var_infos [var_id] .occurences [0]'沒有產生「錯誤:左值需要作爲一元'&'操作數嗎? – krdln