Reinterpret_cast from object to first member
I was looking at this answer and I was wondering if casting an object to its first member with reinterpret_cast and using the result could be safe in C ++.
Suppose we have class A, class B and instance b from B:
class A{
public:
int i;
void foo(){}
};
class B{
public:
A a;
};
B b;
Question 1: Is it safe to use ba like this reinterpret_cast<A*>(&b)->foo()
:?
Note. In general, we assume that the class and its member are standard.
My lecture on available references to reinterpret_cast tells me that this use should be allowed as there is no alias violation, however this conflicts with many answers like this .
Question2: Is it safe to use ba like this static_cast<A*>(static_cast<void*>(&b))->foo()
:?
source to share
Yes, since both classes are standard layout types here , you can convert between &b
and &b.a
.
reinterpret_cast<A*>(p)
is defined as static_cast<A*>(static_cast<void*>(p))
, (5.2.10p7), so both of your questions are equivalent.
For standard layout classes, the address of the struct / class is the same as the address of its first non-static element (9.2p19). And static_cast
to / from will void*
preserve the address (5.2.9p13), which means the result will be valid.
If the classes weren't standard layouts, you couldn't rely on this behavior.
source to share
Formal answer: Yes, there are situations where you can do this (see @ interjay's answer).
Practical answer: Please don't do this. Indeed. Basically when a direct path is available:
b.a.foo();
In other words, don't use machine tricks if there is at least a minimal chance of avoiding them.
source to share
If you're interested in C ++ 98,2003:
Q1 and Q2 are the same constructions.
Your types are POD. There is a guarantee that the POD is not indented at the beginning during instancing .... But it does not exist garantees during inheritance. Therefore reinterpret_cast is unsafe ... my question is about POD placement
"In real life" this is pretty safe because most compilers do memory layout during inheritance, eg http://phpcompiler.org/articles/virtualinheritance.html
But be aware of the risk that the base address of the object and the base address of the object B could have potentially different meanings.
source to share