vendredi 5 juin 2015

The right way to work with network buffer in modern GCC/C++ without breaking strict-aliasing rules

The program - some sort of old-school network messaging:

// Common header for all network messages.
struct __attribute__((packed)) MsgHeader {
    uint32_t msgType;
};
// One of network messages.
struct __attribute__((packed)) Msg1 {
    MsgHeader header;
    uint32_t field1;
};

// Network receive buffer.
uint8_t rxBuffer[MAX_MSG_SIZE];

// Receive handler. The received message is already in the rxBuffer.
void onRxMessage() {
    // Detect message type
    if ( ((const MsgHeader*)rxBuffer)->msgType == MESSAGE1 ) { // Breaks strict-aliasing!
        // Process Msg1 message.
        const Msg1* msg1 = (const Msg1*)rxBuffer;
        if ( msg1->field1 == 0 ) { // Breaks strict-aliasing!
            // Some code here;
        }
        return;
    }
    // Process other message types.
}

This code violates strict-aliasing in modern GCC (and falls down to unspecified behaviour in modern C++). What is the correct way to solve the problem (to make the code that doesn't throw the "strict-aliasing" warning)?

Aucun commentaire:

Enregistrer un commentaire