解决 GCC Warning: "dereferencing type-punned pointer will break strict-aliasing rules" by temporary pointer

Solving GCC Warning: "dereferencing type-punned pointer will break strict-aliasing rules" by temporary pointer

函数中

size_t csps_socket_read(csps_socket_t *s, csps_packet_wrapper_t *packet, size_t sz)

我收到警告:“取消引用类型双关指针将破坏严格别名规则 [-Wstrict-aliasing]”在以下行中:

packet_size = ((csps_packet_full_header_t *)s->receive_mem)->size + header_size;

如果我这样重写:

csps_packet_full_header_t *packet_full_header = (csps_packet_full_header_t *)s->receive_mem;
packet_size = packet_full_header->size + header_size;

我没有收到警告。为什么?是不是问题依旧但是gcc看不到?

这是涉及的结构:

typedef struct csps_socket_t_
{
    void*       fp;
    bool        open;
    uint8_t     receive_mem[CSPS_SOCKET_MEM];
    uint32_t    receive_index;
} csps_socket_t;

typedef struct ATTR_PACKED csps_packet_full_header_t_
{
    uint8_t version:4;
    uint8_t pclass:4;
    uint8_t ch:1;
    uint8_t reserved:7;
    uint16_t size;
    uint16_t sequence;
    uint16_t checksum;
    uint8_t src[8];
    uint8_t dst[8];
} csps_packet_full_header_t;

基本上这是 GCC -Wstrict-aliasing 机制中的一个错误。众所周知,它既会产生错误警告又会错过真正的混叠违规(请参阅开发人员的 this comment)。

这两种情况都存在问题,转换不相关的结构将违反别名规则,并可能导致 GCC 产生意外代码。