简体   繁体   中英

C++ struct reinterpret_cast

Suppose there are two struct A and B. They have a common struct C. I would like to know if it is safe to call reinterpret_cast to A or B to C. if not, is there any way to do so without any performance impact?

struct C
{
    string m_c1;
    int32_t m_c2;
    double m_c3;
    string m_c4;
};

struct A
{
    C m_a1;
    string m_a2;
    int32_t m_a3;
};

struct B
{
    C m_b1;
    string m_b2;
    int32_t m_b3;
    double m_b4;
};
int main(int argc,char *argv[])
{
        A a;
        a.m_a1.m_c1="A";
        a.m_a1.m_c4="AA";

        B b;
        b.m_b1.m_c1="B";
        b.m_b1.m_c4="BB";

        C* pc = reinterpret_cast<C*>(&a);
        cout << pc->m_c1 << " " << pc->m_c4 << endl;

        pc = reinterpret_cast<C*>(&b);
        cout << pc->m_c1 << " " << pc->m_c4 << endl;

        return 1;
}

Why dont you inherit both A,B from C and then use static_cast instead? Should be safer/cleaner.

Indeed in your case, you shouldnt need a cast at all, you should be able to assign A or B ptrs to a C*

As Mike DeSimone points out the string class is not guaranteed to be a standard-layout class, and thus the class C is not standard-layout , which means that you have no guarantees of the memory layout at all. So it is not safe . Only if you change the string to a (const) char* it will be guaranteed to be safe.

Even then it will only be safe as long as the layout of the classes stays the same (you cannot change the order of members or change the access specifier on them), and the classes stays without any vtables, this is "safe" in such a way that the compiler will generate code that display the behavior you would like.

This is how ever two guarantees that a software developer seldom is able to give. Also the code is hard to understand written like this. Another developer (or the same developer a month later) might ignore the this code (or simply don't understand it), and do the changes needed, and suddenly the code is broken and you got some hard to catch errors on your hand.

A and B are classes that give access to a C (or some members of C ). More readable and thus more safe solutions are:

  • Create an accessor for both A and B , this would probably be inlined and incur no performance penalty.
  • If there is any reason for inheritance use simple inheritance. Either A and B is-a ClassThatHasAC or A and B is-a C As long as there are no virtual functions you would probably not see any performance issues here either. In both cases an accessor would provide you benefits probably without any performance cost.

Create some simple and readable code at first, and measure performance. Onli if this C access is costing you too much, optimize. But if your optimization boils down to the reinterpret cast trick make sure that there are plenty of warning signs around to make sure that no one steps on this booby trap.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM