Code 1:
template<class T>
const PtrInterface<T>*
PtrInterface<T>::newRef() const {
PtrInterface<T>* me = (PtrInterface<T>*) this;
++me->references_;
//++this->references_;
return this;
}
Code 2:
template<class T>
const PtrInterface<T>*
PtrInterface<T>::newRef() const {
//PtrInterface<T>* me = (PtrInterface<T>*) this;
//++me->references_;
++this->references_;
return this;
}
Is there ever any situation where these two blocks of code will do different things?
Thanks!
Yes, when you are in a
constmethod. Currently, the one withmeinvokes undefined behavior. Here’s why:As you know, when you call a member function, there is an implicit
thispointer. Thethispointer isconstwhen a function is markedconst. Take this for example:Implicitly, the compiler generates (by the way, this is simplified):
So, are these two bodies the same?
The answer is it depends, and as stated earlier, it’s dependent on the
const-ness of the function. In a non-constfunction, they are the same:But in a
constfunction:We end up stripping the
constaway. So, no, they aren’t always the same. This is the peril of the C-style cast: it will find a way. By the way, castingconstaway in itself isn’t undefined behavior; it’s the modification of said variable that does it.There is a sticky problem in your question though: your code shouldn’t compile. Like in the commented code above, in your
constmethod you shouldn’t be able to modifyreference_.This is different if
reference_ismutable, which I’m guessing it might be (assuming you gave us compilable code.) In this case, I’m not certain if the first sample leads to undefined behavior, since it wasmutablein the first place. I wouldn’t take the chance though.