Re: [Re: [gtkmm] ANNOUNCE: gtkmm 2.2.8]



On Sunday 05 October 2003 5:33 pm, Chris Vine wrote:

> I agree that in our case, since there is no multiple inheritance, the right
> result is almost certainly given by a reinterpret_cast in practice (at
> least, as long as parent and child either both have v-tables or neither
> have v-tables, as I suppose that could possibly affect offsets, I am not
> really sure, and may be implementation dependent).  The standard only
> guarantees the result of a reinterpret_cast to be usable where the cast it
> to a type (such as an int) large enough to take all its bits and it is then
> cast back again to the same type as the original.

Maybe my "at least" should have been stronger.  I quick test rig below 
illustrates this.  On a typical run on gcc-3.2.3 it gives this result:

Address of B object is:             0xbffff760
Result of static_cast to A* is:     0xbffff764
Result of reintepret_cast to A* is: 0xbffff760
B object destroyed

This shows the offset adjustment in action with static_cast and not with 
reinterpret_cast.  Clearly this problem arises when a new v-table is added to 
the derived class.  Presumably it would also happen when adding a virtual 
method on any implementation where that causes the offset adjustment to 
change (that is, where the address of the object represents that of the 
v-table itself, rather than a pointer to the v-table).

Chris

Test rig:
/////////////////////////////////////////////////////////////////////////

#include <iostream>

class A {
public:
  int a;
};

class B: public A {
public:
  int b;
  virtual ~B(void) {std::cout << "B object destroyed" << std::endl;}
};

int main() {

  class B obj;

  A* a = static_cast<A*>(&obj);
  A* aa = reinterpret_cast<A*>(&obj);
  B* b = &obj;

  std::cout << "Address of B object is:             "
            << static_cast<void*>(b) << std::endl;
  std::cout << "Result of static_cast to A* is:     "
            << static_cast<void*>(a) << std::endl;
  std::cout << "Result of reintepret_cast to A* is: "
            << static_cast<void*>(aa) << std::endl;
 
  return 0;
}

/*
 * Note, the static_cast to void* is for the purpose of displaying the address
 * correctly in hex, and doesn't change the pointer conversions
 */




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]