[Moved from Bugzilla to somewhere more appropriate] (In reply to comment #28) > New is not bared from the standard from seeing the type. Yes it is. In the scope of a member function of A, the type of "this_type" is A. If you cast some raw memory to A*, how is operator new supposed to know that you really wanted to cast it to B* ? If you want to use that memory as a B instance, cast the memory to B*. It's not rocket science. If you lie to the compiler expect to get hurt. If you don't want that, don't lie to the compiler about the type. > So I continue to say it is wrong to close this. Either the compiler should be > giving at least an error for illegal access to the object, The compiler can't always tell when you do something wrong. Let's look at your code from http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53225#add_comment For this statement: B *b_pt = new(5) B; The compiler does two things, call an allocation function, and construct a B: void* mem = operator new(sizeof(B), 5); B *b_pt = new(mem) B; Fir the first step the compiler looks for a suitable allocation function for this type, and it finds A::operator new and it calls A::operator new(sizeof(B), 5) Inside operator new: void* operator new(size_t enfacia_size, uint count){ size_t total_size = enfacia_size + sizeof(int) * count; // the 'tail' ; this_type *new_pt = (this_type *)malloc(total_size); Let's break this into into its two constituent expressions: void* vp = malloc(total_size); this_type *new_pt = (this_type *)vp; The malloc calls returns some memory, let's say it's 0x08. Then you cast that memory to this_type* which is a typedef for A* (I hope you now agree that this_type* is A*, it can't possibly be anything else because you never declared another this_type, and the one in scope in A::operator new is A::this_type.) new_pt->count = count; Now you assign to the "count" member of an A object at 0x08. The A::count member is at offset 0 inside an A object, so that write happens to 0x08. return new_pt; The operator new function returns the memory address 0x08. So now we've got to here: void* mem = 0x08; // value 5 written to integer at address 0x08 B *b_pt = new(mem) B; The next statement constructs a B at the address 0x08. That constructs the C sub-object (that subobject will be at address 0x08 i.e. the 'this' pointer inside the C constructor will be 0x08) Then it constructs the A sub-object at the next memory location, i.e in the A::A constructor the 'this' pointer is the address 0x0a. That means that the "count" member of the A object is also at address 0x0a. Finally the compiler calls the B constructor, with this=0x08. So now when you say b_ptr->count you are accessing 0x0a, but when you wrote to new_ptr->count in operator new you wrote to 0x08. So there's no compiler bug, it's doing exactly what you told it to. You cast the memory returned by malloc to A* and accessed it as an A object, but when the compiler constructed a B at that address the A base class is placed at a different location.