C++ 严格别名警告,创建对无符号字符数组的uint32_t引用+;抵消
在GNU GCC 4.7.0+中,我得到了一些严格的别名警告,我想解决这些问题 我有一个有效载荷(来自硬件): 我有这样一句话:C++ 严格别名警告,创建对无符号字符数组的uint32_t引用+;抵消,c++,c++11,g++,gcc-warning,C++,C++11,G++,Gcc Warning,在GNU GCC 4.7.0+中,我得到了一些严格的别名警告,我想解决这些问题 我有一个有效载荷(来自硬件): 我有这样一句话: *(uint32_t*)(payload + davidlt::DATA_OFFSET) = (pid & davidlt::PID_MASK) << davidlt::PID_SHIFT; 我希望通过使用重新解释cast来解决这个问题,但我得到了同样的警告 *reinterpret_cast<uint32_t *>(payload
*(uint32_t*)(payload + davidlt::DATA_OFFSET) = (pid & davidlt::PID_MASK) << davidlt::PID_SHIFT;
我希望通过使用重新解释cast
来解决这个问题,但我得到了同样的警告
*reinterpret_cast<uint32_t *>(payload + davidlt::DATA_OFFSET) = (pid & davidlt::PID_MASK) << davidlt::PID_SHIFT;
*重新解释投射(有效载荷+吊杆::数据偏移量)=(pid&davidlt::pid_掩码)该联合也将是未定义的行为。在这方面,您只能使用char
——不允许使用其他类型,其中包括无符号char
,您可以做的是创建uint32\t
的数组。通过这种方式,您可以将其作为uint32\t
访问,但也可以作为无符号字符访问:这并不违反别名规则。是的,允许以字符或无符号字符查看数据,但不允许相反
在这种情况下,您应该使用memcpy。您的行获取一个pid
值,屏蔽它,移动它,然后将它插入有效负载。直接翻译为:
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);
无符号字符有效载荷[davidlt::payload_SIZE];
uint32\u t payload\u pid=(pid&davidlt::pid\u MASK)我将数据作为unsigned char
@davidlt,通过适当的强制转换,您可以在声明的uint32\u t
数组中获得unsigned char
数组。最好的解决方案是union
<代码>联合有效负载{无符号字符字节[32];uint32半字[8],uint64半字[4];}代码>但只有当数据对齐时,这才起作用。@davidlt,只有从上次写入的联合成员中读取才定义了行为;使用union来“转换”类型仍然会调用未定义的行为(并且在大多数平台上都可以工作,但这并不能保证)。
*reinterpret_cast<uint32_t *>(payload + davidlt::DATA_OFFSET) = (pid & davidlt::PID_MASK) << davidlt::PID_SHIFT;
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);
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);