Search code examples
c++c++11reinterpret-cast

Standard layout type and reinterpret_cast


Am I allowed to cast from my class to a structure if i have copied the members of the structure to my class?

#include <stdint.h>
#include <sys/uio.h>

class Buffer
{
public:
    void * address;
    size_t size;

    Buffer(void * address = nullptr, size_t size = 0)
        : address(address), size(size)
    {
    }

    operator iovec *() const
    {
        // Cast this to iovec. Should work because of standard layout?
        return reinterpret_cast<iovec *>(this);
    }
}

Solution

  • First off, you cannot cast away constness:

    §5.2.10p2. The reinterpret_cast operator shall not cast away constness (§5.2.11). (...)

    So you need at least to write that as

    operator iovec const*() const
    {
        return reinterpret_cast<iovec const*>(this);
    }
    

    or

    operator iovec *()
    {
        return reinterpret_cast<iovec *>(this);
    }
    

    On top of that, you need to have both Buffer and iovec be standard-layout types, and iovec cannot have an alignment stricter (i.e. larger) than Buffer.

    §5.2.10p7. An object pointer can be explicitly converted to an object pointer of a different type. When a prvalue v of type “pointer to T1” is converted to the type “pointer to cv T2”, the result is static_cast<cv T2*>(static_cast<cv void*>(v)) if both T1 and T2 are standard-layout types (§3.9) and the alignment requirements of T2 are no stricter than those of T1, or if either type is void. (...)

    You also need to be careful not to break the strict aliasing rules: in general, you cannot use two pointers or references to different types that refer to the same memory location.