http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53225

--- Comment #7 from Jonathan Wakely <redi at gcc dot gnu.org> 2012-05-04 
18:31:31 UTC ---
(In reply to comment #6)
> So for example, if an parent class has a method, say increment(), that affects
> a value to be found in a field at offset, say, 4.  and then that parent method
> is inherited into the child, but the inherited field has moved, say now found
> at offset 8,  the method is modified to access offset 8 - or to more
> technically accurate its type information is modified, the control flow 
> remains
> identical. 

No, that's not how it works. If Base::increment() writes to Base::field then it
is always at the same offset into the Base object. Whether that Base object is
a sub-object of another clas is irrelevant.

In your broken example on stackoverflow the "A::operator new" function always
wrote to offset 4 into the A object. When that A object is 4 bytes into a B
object then it writes 4+4=8, but "A::operator new" knows that A::count is 4
bytes into an A, i.e. this+4 where this has type A*


> So yes, inheritance means a lot of copying and modifications are done to 
> _type_
> at _compile_time_.  After all this work is done at compile time, in static
> typing, the type is embedded in the generated code, the unresolved part of 
> type
> is embedded as symbols to be linked in the link map, and the rest is thrown
> away.  For some reason, this embedding for the inherited operator new is
> incorrect.

No, your understanding of how G++ works is incorrect.  That might be a valid
C++ implementation, but it's not how G++ works, and it's certainly not required
to work like that by the standard.

You seem to think that in "A::operator new" the static type of "this" depends
on whether the dynamic type of the object being allocated is A or B.  That's
incorrect.  The static type of "*this" in "A::operator new" is always A, and
that's why your program doesn't work.  When you use "A::operator new" to
allocate a B, the member B::count will be 8 bytes into the allocated memory,
but you cast the memory to (this_type*) i.e. (A*) and then access A::count,
i.e. 4 bytes into the allocated memory.  When you later construct a B at that
location the B::count member is not at the location you thought it was.

Reply via email to