Do reinterpret_cast double* to unsigned long long* constitue a strict aliasing violation?

112 views Asked by At

To give some context, I'm focusing the case of data serialization/deserialization without being dependent of the platform endianness.

For integral types, we can use the bitwise-shifting operators for that purpose (since they already abstract the system endianness for us).

But in the case of floating-point types, the bitwise-shifting operators are not available (which is a shame IMHO but it's pointless to discuss it).

I was wondering if it is legal to interpret a double value as unsigned long long (assuming both have the same size) and operate the serialization/deserialization operation from it.

For example:

// REQUIREMENTS:
// - I want to serialize the data in big-endian (no matter what is the system endianness)
// - buff size >= sizeof(double)
void serialize(unsigned char * buff, double value)
{
    static_assert(sizeof(double) == sizeof(unsigned long long));

    unsigned long long val = *reinterpret_cast<unsigned long long*>(&value);
    for(std::size_t i = 0; i < sizeof(double); ++i)
        buff[sizeof(double)-1-i] = val >> (i*CHAR_BIT);
}

But I suspect such workaround to be undefined behaviour (due to strict aliasing violation). I'm wondering if it is still possible to perform such serialization of floating-point values without sacrificing portability.

I know I could reinterpret_cast directly into an unsigned char * but then I would need to check the system endianness to properly handle the data, which I want to avoid (if I can).

PS: I know the simplest way would be to send data as text instead (but it's out of the topic here)

0

There are 0 answers