2
在功能解決GCC警告:「提領類型punned指針將打破嚴格走樣規則」的臨時指針
size_t csps_socket_read(csps_socket_t *s, csps_packet_wrapper_t *packet, size_t sz)
我得到警告:「提領型punned指針將打破嚴格走樣規則對下面的行[-Wstrict走樣]「:
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會失去蹤跡。您的代碼具有未定義的行爲,並可能在各種情況下崩潰,或者可能不會;它也取決於位字段的佈局是非常多的實現定義。此外,需要檢查'receive_mem'的對齊方式 - 如果uint16_t成員未對齊,則可能導致崩潰 –
我建議使用'memcpy',如下所示:http://stackoverflow.com/q/17789928您可以看到在任何優化級別下,編譯器都能夠將它理解爲類型雙擊並省略實際的內存副本。 https://godbolt.org/g/r6VoO0 – ephemient
@AnttiHaapala請注意OP在問GCC問題,而不是如何重寫代碼以避免UB。 – yugr