Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compiler added optimization causes different behavior for "final" methods [closed]

struct B { 
  virtual void foo ()
  { cout << "B::foo()\n"; }
};

struct D : B { 
  void foo () //final
  { cout << "D::foo()\n"; }
};

int main ()
{
  B *pB = new B;
  D *pD = static_cast<D*>(pB);
  pB->foo();
  pD->foo();
}

Outputs expected behavior:

B::foo()
B::foo()

If we make the D::foo() final, then the output is pleasantly different:

B::foo()
D::foo()

Which means that virtual functionality is not kicked-in when the method is invoked with pointer/reference of a class which has that method declared as final.
Also it means that, final isn't just a compile-time check but also contributes to runtime behavior.

Is it a standard behavior for all compilers. I have tested with g++4.7.

Edit:
Spawned a new question with clarification. Closing this question.

like image 610
iammilind Avatar asked Nov 28 '25 06:11

iammilind


1 Answers

D *pD = static_cast<D*>(pB);

With this statement, you gave up the right to having sane program behavior. C++ does not require this operation to work if what static_cast is given is not actually of type D or one of D's derived classes (which it isn't).

So it's not optimizations that are thwarting you, just bad code.

There's a reason why dynamic_cast exists; a proper dynamic_cast would have quickly failed on this, returning nullptr for an illegal cast.

like image 191
Nicol Bolas Avatar answered Nov 30 '25 19:11

Nicol Bolas