Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
解决GCC警告:“;取消引用类型双关指针将打破严格的别名规则;通过临时指针_C_Pointers_Gcc_Strict Aliasing_Type Punning - Fatal编程技术网

解决GCC警告:“;取消引用类型双关指针将打破严格的别名规则;通过临时指针

解决GCC警告:“;取消引用类型双关指针将打破严格的别名规则;通过临时指针,c,pointers,gcc,strict-aliasing,type-punning,C,Pointers,Gcc,Strict Aliasing,Type Punning,在函数中 size_t csps_socket_read(csps_socket_t *s, csps_packet_wrapper_t *packet, size_t sz) 我得到警告:“取消引用类型punned指针将打破严格的别名规则[-Wstrict aliasing]”在下面的一行: packet_size = ((csps_packet_full_header_t *)s->receive_mem)->size + header_size; 如果我这样重写: csps

在函数中

size_t csps_socket_read(csps_socket_t *s, csps_packet_wrapper_t *packet, size_t sz)
我得到警告:“取消引用类型punned指针将打破严格的别名规则[-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别名机制中的一个缺陷。众所周知,它既会产生错误警告,也会忽略真实的别名冲突(请参阅开发人员提供的)


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

是的,问题仍然存在,但当您使用中间变量时,GCC似乎失去了跟踪。您的代码有未定义的行为,可能在各种情况下崩溃,也可能没有;这也取决于具体的情况,而且位字段的布局在很大程度上是由实现定义的。此外,需要检查
receive\u mem
的对齐情况-如果uint16\u t成员未对齐,这可能会导致Crassesi建议使用
memcpy
,正如下面的回答:您可以看到,在任何优化级别下,编译器都能够将其理解为类型双关,并忽略实际的内存副本@AnttiHaapala请注意,OP询问的是GCC中的问题,而不是如何重写代码以避免UB。@yugr问题的一部分是“问题还在吗?”@AnttiHaapala是的,+1'编辑了您的评论。