在 GNU GCC 4.7.0+ 中,我收到了一些严格的别名警告,我想解决这些警告。
我有一个有效负载(来自硬件):
unsigned char payload[davidlt::PAYLOAD_SIZE];
我有这一行:
*(uint32_t*)(payload + davidlt::DATA_OFFSET) = (pid & davidlt::PID_MASK) << davidlt::PID_SHIFT;
这将创建一个指向有效负载中特定位置的指针,4 个字节被解释为uint32_t
。新的价值uint32_t
类型在有效负载中计算并替换。
I get:
warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
我希望通过使用来解决它reinterpret_cast
,但我收到同样的警告。
*reinterpret_cast<uint32_t *>(payload + davidlt::DATA_OFFSET) = (pid & davidlt::PID_MASK) << davidlt::PID_SHIFT;
据我了解,您可以将任何数据转换为char
or unsigned char
,这是允许的,但这只有一种方式。
一种解决方案是制作一个union
。没有其他方法可以创建不同类型的引用unsigned char
data?
谢谢!
大卫
是的,允许将数据视为 char 或 unsigned char,但反之则不然。
在这种情况下,您应该使用 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);
另一种选择是将有效负载创建为具有适当大小和成员的标准布局类型,然后将其视为无符号字符数组。假设您可以控制有效负载的创建:
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);
这并不违反严格的别名规则,因为它现在正朝着正确的方向发展。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)