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()

:?

+3


source to share


3 answers


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.

+5


source


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.

+4


source


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.

0


source







All Articles