2016-09-06 77 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