c++ - Explain bug behaviour -


can please explain what's going on in buggy example:

base base; derived* d = reinterpret_cast<derived*> (&base); d->method(); d->virtual_method();  //output: derived-method() base-virtual_method()  

i expect code behave other way around. compiler shares single memory layout base , derived, , of course vtable common.

  • when d->method invoked expect compiler "i'm calling method @ offset 0 respect pointer. pointer points base object, object around.
  • when d->virtual_method invoked compiler should going resolve through vtable, , derived method should called (though base object 1 around, layout extends derived).

so expecting see:

//output: base-method() derived-virtual_method() 

base base object; reinterpret bytes derived object , attempt use if derived object. behavior when undefined. program might crash; might appear right thing; might make computer light on fire.

note never correct use reinterpret_cast cast , down class hierarchy. must use static_cast or dynamic_cast (or, if converting base class, no cast may necessary).


to explain why see particular behavior, though: when call nonvirtual member function (as d->method(), assuming method nonvirtual member function of derived), function gets called determined @ compile time, not @ runtime.

here, compiler knows d points d object (because you've lied compiler , said is), generates code calls derived::method(). there no "offset respect pointer" @ all. no computation needs done because function called known when program compiled.

only when call virtual member function table lookup required (and then, lookup required when compiler doesn't know dynamic type of object on member function being called).

when call d->virtual_method(), base::virtual_method gets called. why? in particular implementation of c++, first few bytes of object of class type has virtual member functions (a polymorphic class type) contain tag (called "vptr" or "virtual table pointer") identifies actual type of object. when call virtual member function, @ runtime tag inspected , function called selected based on tag.

when reinterpret base derived object, don't change object itself, tag still states base object, hence why base::virtual_method gets called.

remember, though, happens happens when compile code particular version of particular compiler. behavior undefined , 1 way undefined behavior can manifest itself.


Comments