Can't i typecast a class of size 8 bytes to uint64_t?

407 Views Asked by At

Suppose we have below code:

class A {
        uint32_t X;
        uint32_t Y;
};

int main ()
{
    A a;
    uint64_t num  = (uint64_t)a;
}

The compiler gives error: "Cannot convert from A to uint64_t. No User define conversion operator defined."

Is the error expected and if yes, why?

3

There are 3 best solutions below

0
On

You haven't specified the 'endianness' of your representation. If you want x to be the high word and y the low word, you could add a cast operator to your class:

explicit operator uint64_t () const noexcept
{
    return ((static_cast<uint64_t>(X) << 32) | Y);
}

A '(uint64_t) obj' or (ideally) 'static_cast<uint64_t>(obj)' will call this method. explicit prevents it being called implicitly - which is probably the dumbest thing I've said all day - but it prevents surprises. Extra points if you use <cstdint> and std::uint64_t.

3
On

Definitely undefined behavior, but try

uint64_t num  = *reinterpret_cast<uint64_t *>(&a);
0
On

You need to explicitly copy the 32 bits of one value to the upper 32 bits of the 64-bit value, and the other 32 bits to the lower 32 bits of the 64-bit value.

All other methods are technically undefined behavior (although if you know your implementation details well enough, they can work).

class A
{
    uint32_t X;
    uint32_t Y;
    uint64_t to64()
    {
        // convert X and Y to unsigned 64-bit ints
        uint64_t x64 = X;
        uint64_t y64 = Y;
        // left-shift the 64-bit X 32 bits
        x64 <<= 32;

        // return the sum
        return( x64 + y64 );
    }
};

You can do it with much less code, but this shows what you need to do in a step-by-step way.