Strict aliasing warning, creating uint32_t reference to unsigned char array + offset

淺唱寂寞╮ 提交于 2019-12-06 03:37:58

Yes, viewing data as char or unsigned char is allowed, but not the reverse.

Instead you should use memcpy in this case. Your line takes a pid value, masks it, shifts it, and then inserts it into the payload. A direct translation of this would be:

unsigned char payload[davidlt::PAYLOAD_SIZE];

uint32_t payload_pid = (pid & davidlt::PID_MASK) << davidlt::PID_SHIFT;

std::memcpy(payload + davidlt::DATA_OFFSET, &payload_pid, sizeof payload_pid);

Another alternative would be to create your payload as a standard layout type with the appropriate size and members, and then to view it as an unsigned char array. Assuming you're in control of creating the payload:

struct Payload {
    ...
    uint32_t pid;
    ...
} payload;

payload.pid = (pid & davidlt::PID_MASK) << davidlt::PID_SHIFT;

static_assert(davidlt::PAYLOAD_SIZE == sizeof(Payload), "");

unsigned char (&payload_as_char)[davidlt::PAYLOAD_SIZE] = reinterpret_cast<unsigned char (&)[davidlt::PAYLOAD_SIZE]>(&payload);

This isn't violating the strict aliasing rule because it's going the right direction now.

The union would also be undefined behaviour. You can only use char in this respect- no other type is allowed, and that includes unsigned char.

What you can do is to create an array of uint32_t instead. This way you could access them as uint32_t but also as unsigned char: this does not violate the aliasing rules.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!