This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c++/53225] static operator new in multiple inheritance carries incorrect type information for the class
- From: "redi at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Fri, 04 May 2012 18:31:31 +0000
- Subject: [Bug c++/53225] static operator new in multiple inheritance carries incorrect type information for the class
- Auto-submitted: auto-generated
- References: <bug-53225-4@http.gcc.gnu.org/bugzilla/>
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.