Search code examples
c++language-lawyerdowncasttype-punning

C-style cast on a non-polymorphic type


Suppose I have a base struct FOO which is essentially a C-style struct:

struct FOO
{
    double bar1;
    int bar2;
};

And a C++ style struct (which has member functions, no member data, but no v-table):

struct bar : public FOO
{
    double getBar1() const;
    int getBar2() const;
};

I then have a pointer FOO* f, which is actually a FOO: it was created using FOO* f = new FOO(); Is the C-style cast bar* b = (bar*)(f) defined?

Apologies: bar does not contain any data members


Solution

  • I agree with the answer by iammilind - your casting is the same as static_cast, and it's not defined.

    The Standard (the linked document is actually a draft, but it doesn't matter for most purposes) says "the result of the cast is undefined" in section 5.2.9, which describes static_cast.

    However, since your struct bar has no data members, it's a standard-layout class, and it's layout-compatible with struct FOO. So you can cast your pointer to void* and then to foo*:

    bar* b = (bar*)(void*)f
    

    This is better represented in c++ by reinterpret_cast:

    bar* b = reinterpret_cast<bar*>(f)
    

    This is described in section 5.2.10:

    An object pointer can be explicitly converted to an object pointer of a different type ... the result is static_cast<cv T2*>(static_cast<cv void*>(v)) if both T1 and T2 are standard-layout types ...