Cast array of bytes to POD

只谈情不闲聊 提交于 2019-12-03 00:27:16

The most correct way is to create a (temporary) variable of the desired POD class, and to use memcpy() to copy data from the buffer into that variable:

switch(buffer[0]) {
    case 0: {
        Pod1 var;
        std::memcpy(&var, &buffer[4], sizeof var);
        process(var);
        break;
    }
    case 1: {
        Pod2 var;
        std::memcpy(&var, &buffer[8 + buffer[1] * 4], sizeof var);
        process(var);
        break;
    }
    //...
}

There main reason for doing this is because of alignment issues: the data in the buffer may not be aligned correctly for the POD type you are using. Making a copy eliminates this problem. It also allows you to keep using the variable even if the network buffer is no longer available.

Only if you are absolutely sure that the data is properly aligned can you use the first solution you gave.

(If you are reading in data from the network, you should always check that the data is valid first, and that you won't read outside of your buffer. For example with &buffer[8 + buffer[1] * 4], you should check that the start of that address plus the size of Pod2 does not exceed the buffer length. Luckily you are using uint8_t, otherwise you'd also have to check that buffer[1] is not negative.)

Using a union allows to escape anti-aliasing rule. In fact that is what unions are for. So casting pointers to a union type from a type that is part of the union is explicitly allowed in C++ standard (Clause 3.10.10.6). Same thing is allowed in C standard (6.5.7).

Therefore depending on the other properties a conforming equivalent of your sample can be as follows.

union to_pod {
    uint8_t buffer[100];
    Pod1 pod1;
    Pod1 pod2;
    //...
};

uint8_t buffer[100]; //filled e.g. from network

switch(buffer[0]) {
    case 0: process(reinterpret_cast<to_pod*>(buffer + 4)->pod1); break;
    case 1: process(reinterpret_cast<to_pod*>(buffer + 8 + buffer[1]*4)->pod2); break;
    //...
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!