More specifically, assuming A
is an accessible base class of B
, does the following code produce undefined behavior, and is the assertion guarenteed not to fire according to the standard?
void test(B b1, B b2) {
A* a2 = &b2;
auto offset = reinterpret_cast<char*>(a2) - reinterpret_cast<char*>(&b2);
A* a1 = reinterpret_cast<A*>(reinterpret_cast<char*>(&b1) + offset);
assert(a1 == static_cast<A*>(&b1));
}
Edit:
I'm aware that all of the common compiler vendors implement C++ object layout (even when taking into account virtual inheritence) in a way that is compatible with the implicit assumptions of test
. What I'm looking for is a guarantee (either implicit or explicit) for this behavior in the standard. Alternatively, a reasonably detailed description of the extent of object storage layout guarantees provided by the standard, as proof that this behavior is not guaranteed, will also be accepted.
That may be fine. Under some specific conditions:
A
is not (part of) avirtual
base, orb1
andb2
have the same most derived type, or you happen to be (un-)lucky.Edit: Your change from pass-by-reference to pass-by-value makes it trivial to show the condition above holds.
The aliasing-rules won't get in the way as the only wrong type used is
char
, and there is an explicit exception for that.