Dans la fonctionRésolution Avertissement GCC: "pointeur punned de type déréférencement brisera des règles strictes-aliasing" par pointeur temporaire
size_t csps_socket_read(csps_socket_t *s, csps_packet_wrapper_t *packet, size_t sz)
Je reçois l'avertissement: "pointeur de type punned déréférencement brisera stricte-aliasing règles [-Wstrict-aliasing] "sur la ligne suivante:
packet_size = ((csps_packet_full_header_t *)s->receive_mem)->size + header_size;
Si je réécris comme ceci:
csps_packet_full_header_t *packet_full_header = (csps_packet_full_header_t *)s->receive_mem;
packet_size = packet_full_header->size + header_size;
Je ne reçois aucun avertissement. Pourquoi? Le problème est toujours là mais gcc ne peut pas le voir?
est ici les struct impliqués:
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;
Oui, le problème est toujours là, mais il semble que GCC perd la trace lorsque vous utilisez une variable intermédiaire. Votre code a un comportement indéfini et peut se bloquer dans diverses circonstances, ou peut-être pas; Cela dépend aussi de la configuration de bitfields. En outre, l'alignement de 'receive_mem' doit être vérifié - si les membres uint16_t sont mal alignés, cela peut provoquer des plantages –
Je recommande d'utiliser' memcpy', comme dans cette réponse: http://stackoverflow.com/q/17789928 Vous pouvez voir que sous n'importe quel niveau d'optimisation, le compilateur est capable de le comprendre comme type-punning et omettre la copie de la mémoire réelle. https://godbolt.org/g/r6VoO0 – ephemient
@AnttiHaapala S'il vous plaît noter que OP pose des problèmes sur GCC, pas comment réécrire le code pour éviter UB. – yugr