Reputation: 63
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.
Upvotes: 6
Views: 2188
Reputation: 85371
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];
}
Upvotes: 5