Gray0Ed Gray0Ed - 3 months ago 6
C++ Question

Can address of const reference be different than address of referenced object?

I've run into trouble with code equivalent to the following:

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


When I compile it with g++ -O3 flag, it doesn't pass through the assertion. When it's compiled without optimizations assertion is passed.

As far as I know, even if there are UBs in my project such situation shouldn't be possible.

Are there any circumstances when such behavior of reference is expected?

EDIT:
Link to the actual code: https://github.com/Gray0Ed/ggp_thesis/blob/67606021020546b315ad63b7fd5c2203f3e0086f/rule_engine/aligner.cpp#L177 - project is a bit messy and it's not really ready to be publicly shown, but feel free to look at it if you're curious.

EDIT2:
As RustyX pointed original code differs from the "equivalent" I've given above, check his answer to see the details.

Answer

This code will always work:

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

The actual code that doesn't work is in fact this:

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

It doesn't work because you overload operator[]:

See MyArrays.hpp:

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

This returns a copy every time it's invoked.

It should probably be:

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