2
로 "역 참조 형 punned 포인터가 엄격한 앨리어싱 규칙을 깰 것"해결 GCC 경고 : 함수에서 임시 포인터
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;
I는 다음과 같이 다시 쓸 경우
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는 UCC를 피하기 위해 코드를 다시 작성하는 방법이 아니라 GCC의 문제에 대해 질문합니다. – yugr