Type punning. What is allowed?

Viewed 757

I am sending udp packets across the network. The messages consist of a header and a part that can differ from message to message. The header contains a tag so that the receiver knows how to interpret the data. Ie something like this

struct Datagram {
    uint8_t message_type;
    uint8_t length;
    uint8_t data[MAX_SIZE];
};

the receiver would do something like this

void readMessage(Datagram* data){
    uint8_t* ptr = (uint8_t*)data;
    uint8_t type = *ptr;
    ptr++;
    uint8_t size = *ptr;
    ptr++;
    if (type == 0) { 
        uint16_t* x = (uint16_t*)ptr;
        //...
    } else if (type == 1) {
        //...
    }

I have done similar things before and never encountered a problem with such casts. However, now I read about type punning and from here I understand that the only other types I would be allowed to cast a Datagram* to is char, unsigned char or std::byte. However, I would need it the other way around (ie receiving into a buffer char[MAX_SIZE] and then reinterpreting as something different, which isnt allowed).

Now I am a bit confused how I should interpret the raw Datagram. Am I missing something, or is there really no (safe) way to reinterpret an array of bytes as something different? What is the common way to reinterpret a raw stream of bytes as a certain type?

PS: There are quite some q/a s on type punning on SO, but the ones I found mainly concentrate on C (even if tagged as C++).

0 Answers
Related