Search code examples
c++castingtype-conversionreinterpret-caststrict-aliasing

(How) can I cast between an aggregate type with one member and that member's type?


Is it possible to do this?

struct compound_type {
    int member;
};

void func()
{
    compound_type foo {384};
    int bar = sole_member_type_cast<int>(foo); // doesn't compile; there's no such thing
                                               // reinterpret_cast wouldn't compile here
    std::cout << bar << std::endl; // prints 384
}

I know it's possible with pointer aliasing, but it seems like this is a strict aliasing problem. (Is it?) Unions are also used, but again you aren't supposed to do so, as a union type "can hold only one of its non-static data members at a time" (ref).

In any case, would there be alignment or offset problems with this?


Solution

  • Yes, you can do:

    int bar = *reinterpret_cast<int*>(&foo); 
    

    This is well defined since objects of compound_type and int are pointer-inter-convertible. The address of foois the same as the address of its first data member which is an int, and so the reinterpret_cast is well defined.


    As pointed out in the comments by @Remy Lebeau, the conversion could be simplified to:

    int bar = reinterpret_cast<int&>(foo); 
    

    which is much easier to read, and write.