In the following question one of the answers suggested that the dynamic type of an object cannot change: When may the dynamic type of a referred to object change?
However, I've heard that it is not true from some speaker on CPPCon or some other conference.
And indeed it does not seem to be true, because both GCC and Clang re-read vtable pointer on every loop iteration of the following example:
class A {
public:
virtual int GetVal() const = 0;
};
int f(const A& a){
int sum = 0;
for (int i = 0; i < 10; ++i) {
// re-reads vtable pointer for every new call to GetVal
sum += a.GetVal();
}
return sum;
}
However, if one adds the following:
class B final : public A {
public:
int GetVal() const override {
return 1;
}
};
int g(const B& b){
int sum = 0;
for (int i = 0; i < 10; ++i) {
sum += b.GetVal();
}
return sum;
}
then function g is simplified to return 10;, which is indeed expected because of final. It also suggests that the only possible place where the dynamic may change is inside GetVal.
I understand that re-reading vtable pointer is cheap, and asking mostly because of pure interest. What disables such compiler optimizations?